How can I use ES6 in webpack.config.js?
Asked Answered
V

19

262

How to use ES6 in webpack.config ? Like this repo https://github.com/kriasoft/react-starter-kit does ?

For instance:

using this

import webpack from 'webpack';

instead of

var webpack = require('webpack');

It is quite a curiosity rather than a need.

Vicinage answered 9/8, 2015 at 11:23 Comment(4)
The question is how to use es6 in webpack.config.It seems clear to me.I update my question with an example.Vicinage
The file gets parsed by node.js, which doesn't support es6 by default. There are command line flags to turn this on, but I don't know what they are. You might also try using io.js instead of nodeLevel
Same problem here. It's extremely confusing because webpack itself DOES support ES6 module syntax! But in webpack.config you still have to use require. It seems overkill to install babel JUST for the webpack config file!Dionnadionne
Webpack documentation says webpack.js.org/api/module-methods/#es6-recommended- ES6 syntax can be used without need of babel. Did anyone succeed using ES6 syntax import without using babel?Taskwork
A
252

Try naming your config as webpack.config.babel.js. You should have babel-register included in the project. Example at react-router-bootstrap.

Webpack relies on interpret internally to make this work.

Aphasia answered 9/8, 2015 at 17:28 Comment(17)
This worked for me. I npm run this script: webpack --config webpack.config.babel.js.Araiza
I think it might be able to pick it up directly even without --config.Facer
@bebraw are you sure the required package is babel and not babel-core? I can get it to work with just the latter but not just the former. I'm confused by this, however, because babel depends on babel-core. Should work with either standalone.Phlebosclerosis
I think it should be added that the babel-loader module is also requiredLot
I think this may not work as expected when using webpack 1.12.x with babel 6. That version of webpack relies on an old version of interpret (6.4) which does not know about the new babel 6 register modules. Either downgrade babel 6, hack webpack to use the new interpret version (1.0), or upgrade webpack to an unstable dev version.Trey
Actually, it works fine, just need to set your babel presets in a .babelrc file.Trey
I used this specific preset to get this to work: echo '{ "presets": ["es2015"] }' > .babelrcIrrawaddy
@skymk Reading from the source I would say yes. It still relies on interpret.Facer
this is too good to be true. I still cannot understand who is picking up the file webpack.config.babel.js instead of webpack.config.js. Who is telling webpack command line to pick up that file instead?Vickyvico
+Ghassan Karwchan. It's interpret. You can find the other supported formats there as well.Facer
@GhassanKarwchan I looked a bit into this, see hereManse
This cured my OCD. Thank you! using requires in the webpack config where every other file is importing made me squirm every time.Lifeguard
Webpack will find webpack.config.babel.js without you explicitly passing config filename via command line options. babel-loader is not needed for webpack.config.babel.js to be successfully processed. For it to work you basically need to rename webpack.config.js to webpack.config.babel.js and one of these three packages. More details here.Peneus
...Depending on your node version and what features you're going to use you might need .babelrc with list of plugins/presets. For .babelrc to not be in the way of your project code, you might consider looking at this answerPeneus
Running with webpack 4, I get SyntaxError: Unexpected token import, whereever I did import x from 'y'. So I will assume this solution does not work with webpack 4?Geniculate
@Geniculate Can you link to your project? How did you configure Babel? It crashes like that if you disabled module transformation.Facer
I finally got it working. See my answer https://mcmap.net/q/109086/-how-can-i-use-es6-in-webpack-config-jsGeniculate
A
45

As an alternative to what @bebraw suggests, you can create a JavaScript automation script with ES6+ syntax:

// tools/bundle.js

import webpack from 'webpack';
import webpackConfig from './webpack.config.js'; // <-- Contains ES6+

const bundler = webpack(webpackConfig);

bundler.run(...);

And execute it with babel:

$ babel-node tools/bundle

P.S.: Calling webpack via JavaScript API might be a better approach (than by calling it via a command line) when you need to implement more complex build steps. E.g. after server-side bundle is ready, startup Node.js app server, and right after Node.js server is started, launch BrowserSync dev server.

See also:

Amuck answered 11/8, 2015 at 21:18 Comment(1)
Although a little complex, this is exactly what react-starter-kit uses. It should be the best answer.Rorrys
J
20

Another approach is to have a npm script like this: "webpack": "babel-node ./node_modules/webpack/bin/webpack", and run it like so: npm run webpack.

Jaal answered 19/3, 2016 at 13:13 Comment(1)
This doesn't seem to work when passing a custom config to webpack babel-node ./node_modules/webpack/bin/webpack --config custom-webpack.configHamon
G
17

This is what worked for me using webpack 4:

In package.json:

"scripts": {
    "dev": "cross-env APP_ENV=dev webpack-serve --require @babel/register"
},

"devDependencies": {
    "@babel/core": "^7.0.0-rc.1",
    "@babel/register": "^7.0.0-rc.1",
    "@babel/preset-env": "^7.0.0-rc.1",
    "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2"
},

"babel": {
  "presets": [
    ["@babel/preset-env", {
      "targets": {
        "node": "current"
      }
    }]
  ],
  "plugins": [
    "transform-es2015-modules-commonjs"
  ]
}

You can clearly see how each dependency is used, so no surprises there.

Note I am using webpack-serve--require, but if you want to use the webpack command instead, replace it with webpack --config-register. In either case, @babel/register is needed to make this work.

And that's it!

yarn dev

And you are able to use es6 in the config!


For webpack-dev-server, use the --config-register option which is the same as with the webpack command


NOTE:

NO need to rename the config file to webpack.config.babel.js (as suggested by the accepted answer). webpack.config.js will work just fine.

Geniculate answered 9/8, 2018 at 19:13 Comment(3)
Looks like web-serve is deprecated. Any idea of how to make this work with webpack-dev-server? I'm not seeing a --require option for it in the docs: webpack.js.org/configuration/dev-server/#devserverGuinness
@CrhistianRamirez, use the --config-register option. Also the repo for webpack-serve moved here: github.com/shellscape/webpack-serveGeniculate
Cool! that worked for me. Here's what my script looks like: webpack --config-register @babel/register --config webpack/development.config.js I had to specificy --config because my webpack config is in a folder. Thank you!Guinness
C
17

For readers in 2024 who are also using tsconfig.json with the newest TSConfig option "moduleResolution": "bundler":

  1. Remove "type": "module" in package.json. (see the issue)
  2. Rename webpack.config.js into webpack.config.mjs (confirmed with the maintainer of webpack 2024/3/7)
  3. Enjoy.

For readers in 2022:

"webpack": "^5.70.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.7.4"
  1. Add "type": "module" in package.json

  2. Change the syntax of your webpack.config.js to ESM.

  3. Enjoy.

Cockerham answered 26/3, 2022 at 8:21 Comment(1)
Could you provide an example of what you ended up with for step 2?Somali
O
15

I had a problem getting @Juho's solution running with Webpack 2. The Webpack migration docs suggest you to turn of babel module parsing:

It is important to note that you will want to tell Babel to not parse these module symbols so webpack can use them. You can do this by setting the following in your .babelrc or babel-loader options.

.babelrc:

{
    "presets": [
         ["es2015", { "modules": false }]
    ]
}

Sadly, this conflicts with the automatic babel register functionality. Removing

{ "modules": false }

from the babel config got things running again. However, this would result in breaking tree-shaking, so a complete solution would involve overwriting the presets in the loader options:

module: {
    rules: [
        {
            test: /\.js$/,
            include: path.resolve('src'),
            loader: 'babel-loader',
            options: {
                babelrc: false,
                presets: [['env', {modules: false}]]
            }
        }
    ]
}

Edit, 13th Nov 2017; updated webpack config snippet to Webpack 3 (thanks to @x-yuri). Old, Webpack 2 snippet:

{
    test: /\.js$/,
    exclude: ['node_modules'],
    loader: 'babel',
    query: {
        babelrc: false,
        presets: [
            ['es2015', { modules: false }],
        ],
    },
},
Ogilvie answered 2/3, 2017 at 13:35 Comment(3)
These days (Webpack 3), it would probably look like this: module:{rules: [{test: /\.js$/, include: path.resolve('src'), loader: 'babel-loader', options: {babelrc: false, presets: [['env', {modules: false}]]}}]} (gist). -loader suffix no longer optional. Try to avoid exclude and prefer include. Strings in include/exclude work only if absolute paths. query was renamed to options.Peneus
Also, make it clear please that you don't want {modules: false} in .babelrc to be able to use import's in webpack.config.babel.js.Peneus
For Webpack 4 -loader suffix needs to be added back webpack.js.org/migrate/3/…Analiese
N
13

This is really easy, but it wasn't obvious to me from any of the answers, so if anyone else is confused like me:

Just append .babel to the part of your filename before the extension (assuming that you have babel-register installed as a dependency).

Example:

mv webpack.config.js webpack.config.babel.js
Nannana answered 18/11, 2016 at 18:19 Comment(2)
I don't use babel because webpack itself already supports ES6 module syntax, and my project doesn't need to be compatible with ES5. It's just the config file that still needs require. That's weird isn't it?Dionnadionne
Woah that’s interesting! I didn’t know that. I’ll need to revisit this. Weird that the configs file still requires requireNannana
D
8

For TypeScript: straight from https://webpack.js.org/configuration/configuration-languages/

npm install --save-dev typescript ts-node @types/node @types/webpack
# and, if using webpack-dev-server
npm install --save-dev @types/webpack-dev-server

then proceed to write your, e.g.: webpack.config.ts

import path from 'path';
import webpack from 'webpack';

const config: webpack.Configuration = {
  mode: 'production',
  entry: './foo.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'foo.bundle.js'
  }
};

export default config;

Check the link for more details where you can use a plugin to have a separate tsconfig file just for the webpack config if you're not targeting commonjs (which is a req for this to work since it relies on ts-node).

Debussy answered 8/1, 2019 at 15:8 Comment(1)
Thanks for this, couldn't get modules working for webpack.config.js but happy to use TypeScript instead which does work.Carinthia
F
7

Configuration for Babel 7 & Webpack 4

package.json

    ...
    "scripts": {
        "start": "webpack-dev-server --env.dev",
        "build": "webpack --env.prod",
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
        "@babel/core": "^7.0.0",
        "@babel/plugin-proposal-class-properties": "^7.0.0",
        "@babel/preset-env": "^7.0.0",
        "@babel/preset-react": "^7.0.0",
        "@babel/register": "^7.0.0",
        "babel-loader": "^8.0.0",
        ...
        "webpack": "^4.17.2",
        "webpack-cli": "^3.1.0",
        "webpack-config-utils": "^2.3.1",
        "webpack-dev-server": "^3.1.8"

.babelrc

{
    "presets": ["@babel/preset-env", "@babel/preset-react"],
    "plugins": ["@babel/plugin-proposal-class-properties"]
}

webpack.config.babel.js

import webpack from 'webpack';
import { resolve } from 'path';

import { getIfUtils, removeEmpty } from 'webpack-config-utils';

export default env => {
    const { ifProd, ifNotProd } = getIfUtils(env);

    return {
        mode: ifProd('production', 'development'),
        devtool: ifNotProd('cheap-module-source-map'),
        output: {
            path: resolve(__dirname, ifProd('prod', 'dev')),
            filename: 'bundle.js'
        },
Feldt answered 10/9, 2018 at 13:54 Comment(1)
This still does not work for me, but IMHO looks to be the most up-to-date and almost cleanest example (class properties related entries are superfluous for the task at hand).Sliwa
S
5

One more way is to use require argument for node:

node -r babel-register ./node_modules/webpack/bin/webpack

Found this way in electron-react-boilerplate, look at build-main and build-renderer scripts.

Syst answered 16/10, 2016 at 17:1 Comment(1)
Spectacular - was just looking at Electron and starting up a separate server, your answer helped perfectly! :)Stagner
S
3

Rename webpack.config.js to webpack.config.babel.js.

Then in .babelrc: {"presets": ["es2015"]}

However, if you want to use a different babel config for babel-cli, your .babelrc might look something like this:

{
  "env": {
    "babel-cli": {
      "presets": [["es2015", {"modules": false}]]
    },
    "production": {
      "presets": ["es2015"]
    },
    "development": {
      "presets": ["es2015"]
    }
  }
}

And in package.json:

{
  "scripts": {
    "babel": "BABEL_ENV='babel-cli' babel src -d dist/babel --source-maps",
    "build-dev": "NODE_ENV='development' webpack -d --progress --profile --colors",
    ...
  },
  ...
}

It's dumb but the {"modules": false} will break webpack if you don't use different envs.

For more info about .babelrc, check the official docs.

Sweaty answered 12/4, 2017 at 6:6 Comment(0)
O
2

Don't have enough rep to comment, but I wanted to add for any TypeScript users out there a similar solution to @Sandrik above

I have two scripts that I use pointing to webpack configs (JS files) that contain ES6 syntax.

"start-dev": "./node_modules/.bin/ts-node ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --config ./webpack/webpack.config.dev.js"

and

"build": "./node_modules/.bin/ts-node ./node_modules/webpack/bin/webpack.js --config webpack/webpack.config.js"

Overshoe answered 16/8, 2017 at 16:8 Comment(0)
P
2

Using Webpack 4 and Babel 7

To setup a webpack configuration file to use ES2015 requires Babel:

Install dev dependencies:

npm i -D  webpack \
          webpack-cli \
          webpack-dev-server \
          @babel/core \
          @babel/register \
          @babel/preset-env
npm i -D  html-webpack-plugin

Create a .babelrc file:

{
  "presets": ["@babel/preset-env"]
}

Create your webpack config, webpack.config.babel.js:

import { resolve as _resolve } from 'path';
import HtmlWebpackPlugin from 'html-webpack-plugin';

const config = {
  mode: 'development',
  devServer: {
    contentBase: './dist'
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'src/index.html'
    })
  ],
  resolve: {
    modules: [_resolve(__dirname, './src'), 'node_modules']
  }
};

export default config;

Create your scripts in package.json:

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack",
    "start": "webpack-dev-server --open"
  },

Run npm run build and npm start.

The webpack config is based on a sample project with the following directory structure:

├── README.md
├── package-lock.json
├── package.json
├── src
│   ├── Greeter.js
│   ├── index.html
│   └── index.js
└── webpack.config.babel.js

Sample project: Webpack Configuration Language Using Babel

Preceptor answered 8/4, 2019 at 11:40 Comment(0)
G
1

My Best approach along with npm script is

node -r babel-register ./node_modules/webpack/bin/webpack

and configure rest of scripts as per your requirement for Babel

Gold answered 13/12, 2016 at 17:17 Comment(0)
S
1

After tons of the documents...

  1. Just install es2015 preset (not env !!!) and add it to

    .babelrc:
    {
        "presets": [
             ["es2015", { "modules": false }]
        ]
    }
    
  2. Rename your webpack.config.js to webpack.config.babel.js

Scratches answered 16/8, 2018 at 8:33 Comment(0)
I
0

Adding es6 to webpack is a 3 step process

  1. In webpack.config.js add

    module:{
    
              rules:[
                {
                  test: /\.js$/,
                  loader: 'babel-loader'
                }
              ]
           }
    
    1. Create a .babel.rc and add inside it
{
    "presets": ["@babel/env", "@babel/react"],
    "plugins": [
        [
          "@babel/plugin-proposal-class-properties",
        ]
      ]
}
  1. in package.json add
npm install @babel/core --save-dev
npm install @babel/preset-env --save-dev
npm install @babel/preset-react --save-dev
npm install @babel/plugin-proposal-class-properties --save-dev
npm install babel-loader --save-dev
Iridissa answered 23/4, 2020 at 1:25 Comment(0)
F
0

Ran into this issue, resolved it by installing lastest webpack, webpack-cli and webpack-devserver see example here

Fabria answered 22/6, 2023 at 19:58 Comment(0)
C
0

The below webpack configuration (in ES6) and package.json work. Essentially the package.json needs to contain "type":"module" indicating the target is ES6. The webpack configuration then needs to export an javascript object whose properties are configuration keys and the values as appropriate. Below is an example:

"use strict"
import webpack from 'webpack';

export default {
    mode: "development", 
    entry: ["./src/lib-junk.jsx"],
    experiments: {outputModule: true},
    output: {
        filename: "lib-junk-dist.js",
        clean: true,
        library: {type: "module"}
    },
    devtool: "source-map",
    module: {
        rules:[
            {
                test: /\.(js|mjs|jsx)?$/,
                loader: 'babel-loader',
                options:{
                    "presets": ["@babel/preset-env", "@babel/preset-react"],
                    "plugins": ["@babel/plugin-syntax-dynamic-import"]
                },
                exclude: [/node_modules/]
            }
                ]
  
                    },
                    externalsType: 'module',
                    externals: {
                        'react': 'react',
                        'react-dom/client': 'react-dom/client',
  
                    },
                    plugins: []
                }

The equivalent CommonJS is as below:

  "use strict"
   const webpack = require('webpack');
    module.exports = {

  mode: "development",

  entry: ["./src/lib-junk.jsx"],

  //Refer: https://mcmap.net/q/111078/-output-an-es-module-using-webpack
  experiments: {outputModule: true},

  output: {
  
    filename: "lib-junk-dist.js",
    
    clean: true,

    //Refer: https://mcmap.net/q/111078/-output-an-es-module-using-webpack
    library: {type: "module"}
  },

  devtool: "source-map",

  module: {
  
    rules:[
        {
            test: /\.(js|mjs|jsx)?$/,
            loader: 'babel-loader',
            //options: babelrc,
            options:{
                        "presets": ["@babel/preset-env", "@babel/preset-react"],
                        "plugins": ["@babel/plugin-syntax-dynamic-import"]
                    },
            exclude: [/node_modules/],
        }
    ]
  
  },

    externalsType: 'module',
    externals: {
  
      'react': 'react',
      'react-dom/client': 'react-dom/client',
  
    },

  plugins: []
  
}

The dependencies for the above in package.json is as below

"files":["components/*","*.mjs"],
    "main":"index.js",
    "type":"module", //This is essential for ES6
    "scripts": {

        "build": "webpack --config build/webpack.config.dev.js"

    },
  
    "dependencies": {
    
        

    },
    
     "peerDependencies": {

        "react": "^18.2.0",
        "react-dom": "^18.2.0"
    
    },
    
    "devDependencies":{
    
        "@babel/core": "^7.0.0",
        "@babel/plugin-syntax-dynamic-import": "^7.0.0",
        "@babel/preset-env": "^7.0.0",
        "@babel/preset-react": "^7.0.0", 
        "babel-loader": "^8.0.1",
        "webpack": "^5.1.4",
        "webpack-cli": "^5.1.4",
        "url-loader":"^4.1.1",
        "file-loader": "^6.0.0"
    
    }

NOTE: In my case I am using Babel to transpile .jsx files only, it is not required for webpack to use this config, far I could figure.

Concertante answered 24/2 at 7:50 Comment(0)
T
-3

Edit: Works as of Feb 2021

https://github.com/webpack/webpack-cli/pull/2381


You can't. You have to convert it to CommonJS, either with babel or esm.

https://github.com/webpack/webpack-cli/issues/282

But you can run webpack -r esm @babel/register

Teplica answered 28/6, 2020 at 22:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.