255

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.

Matthew
  • 28,056
  • 26
  • 104
  • 170
Whisher
  • 31,320
  • 32
  • 120
  • 201
  • @Amit it's a question. I can't figure it out. Because if I use es6 syntax in webpack.config I get errors. – Whisher Aug 09 '15 at 11:28
  • 24
    The question is how to use es6 in webpack.config.It seems clear to me.I update my question with an example. – Whisher Aug 09 '15 at 11:34
  • 1
    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 node – KJ Tsanaktsidis Aug 09 '15 at 11:40
  • @KJTsanaktsidis thanks for the hint but I've also tried with --harmony with no success – Whisher Aug 09 '15 at 11:41
  • I haven't tried this, but try running "node --harmony `which webpack`" – KJ Tsanaktsidis Aug 09 '15 at 11:44
  • Ah ok cool, out of ideas then :) – KJ Tsanaktsidis Aug 09 '15 at 11:47
  • 1
    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! – Kokodoko Sep 28 '17 at 12:48
  • 3
    Webpack documentation says https://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? – barath Sep 20 '19 at 00:38

18 Answers18

251

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.

Juho Vepsäläinen
  • 26,573
  • 12
  • 79
  • 105
  • 4
    This worked for me. I `npm run` this script: `webpack --config webpack.config.babel.js`. – Mat Gessel Sep 08 '15 at 17:38
  • 11
    I think it might be able to pick it up directly even without `--config`. – Juho Vepsäläinen Sep 08 '15 at 17:52
  • @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. – Adam Beck Oct 28 '15 at 18:08
  • @AdamBeck Thanks. Fixed! – Juho Vepsäläinen Oct 29 '15 at 07:30
  • 5
    I think it should be added that the `babel-loader` module is also required – flipchart Jan 01 '16 at 08:22
  • 1
    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. – peter Mar 25 '16 at 20:41
  • 7
    Actually, it works fine, just need to set your babel presets in a .babelrc file. – peter Mar 25 '16 at 20:58
  • 10
    I used this specific preset to get this to work: `echo '{ "presets": ["es2015"] }' > .babelrc` – killthrush Jun 18 '16 at 20:57
  • @bebraw is it still valid for webpack-2 beta? – Valery Bugakov Jul 19 '16 at 08:06
  • @skymk Reading from the [source](https://github.com/webpack/webpack/blob/bc29455e92f4b760db745775a4fca5cde0d01d23/bin/convert-argv.js#L33) I would say yes. It still relies on [interpret](https://www.npmjs.com/package/interpret). – Juho Vepsäläinen Jul 19 '16 at 16:43
  • 2
    I'm in love with your book on Webpack @JuhoVepsäläinen <3 – tu4n May 21 '17 at 07:25
  • 1
    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? – Ghassan Karwchan Aug 02 '17 at 15:34
  • +Ghassan Karwchan. It's [interpret](https://www.npmjs.com/package/interpret). You can find the other supported formats there as well. – Juho Vepsäläinen Aug 02 '17 at 20:00
  • @GhassanKarwchan I looked a bit into this, [see here](https://stackoverflow.com/a/46276592/444255) – Frank N Sep 18 '17 at 10:06
  • This cured my OCD. Thank you! using requires in the webpack config where every other file is importing made me squirm every time. – meza Oct 23 '17 at 21:32
  • 2
    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](https://github.com/js-cli/js-interpret/blob/v1.0.4/index.js#L2-L29). More details [here](https://stackoverflow.com/a/47242644/52499). – x-yuri Nov 11 '17 at 20:56
  • ...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 answer](https://stackoverflow.com/a/42556951/52499) – x-yuri Nov 11 '17 at 20:59
  • 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? – smac89 Aug 09 '18 at 17:38
  • @smac89 Can you link to your project? How did you configure Babel? It crashes like that if you disabled module transformation. – Juho Vepsäläinen Aug 10 '18 at 11:59
  • I finally got it working. See my answer https://stackoverflow.com/a/51774289/2089675 – smac89 Aug 10 '18 at 14:11
44

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:

Konstantin Tarkus
  • 37,618
  • 14
  • 135
  • 121
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.

Igonato
  • 10,175
  • 3
  • 35
  • 64
alexb
  • 880
  • 11
  • 16
  • 1
    This doesn't seem to work when passing a custom config to webpack `babel-node ./node_modules/webpack/bin/webpack --config custom-webpack.config` – Abhinav Singi Apr 26 '19 at 12:27
16

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.

Legends
  • 21,202
  • 16
  • 97
  • 123
smac89
  • 39,374
  • 15
  • 132
  • 179
  • 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: https://webpack.js.org/configuration/dev-server/#devserver – Crhistian Ramirez May 03 '19 at 03:05
  • 1
    @CrhistianRamirez, use the `--config-register` option. Also the repo for `webpack-serve` moved here: https://github.com/shellscape/webpack-serve – smac89 May 03 '19 at 03:18
  • 2
    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! – Crhistian Ramirez May 03 '19 at 03:44
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 }],
        ],
    },
},
Edo
  • 3,311
  • 1
  • 24
  • 25
  • 2
    [These days](https://webpack.js.org/configuration/) (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](https://gist.github.com/x-yuri/46801063e7a8a27c8eb745adf39af725)). `-loader` suffix no longer optional. Try to avoid `exclude` and prefer `include`. Strings in include/exclude [work](https://github.com/webpack/webpack/blob/v3.8.1/lib/RuleSet.js#L300) only if absolute paths. `query` was renamed to `options`. – x-yuri Nov 11 '17 at 22:24
  • 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`. – x-yuri Nov 11 '17 at 22:31
  • For Webpack 4 `-loader` suffix needs to be added back https://webpack.js.org/migrate/3/#automatic-loader-module-name-extension-removed – kmmbvnr Jun 05 '18 at 10:25
12

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.

NeoZoom.lua
  • 2,269
  • 4
  • 30
  • 64
11

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
Dmitry Minkovsky
  • 36,185
  • 26
  • 116
  • 160
  • 1
    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? – Kokodoko Sep 28 '17 at 12:50
  • Woah that’s interesting! I didn’t know that. I’ll need to revisit this. Weird that the configs file still requires require – Dmitry Minkovsky Sep 28 '17 at 12:52
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'
        },
keemor
  • 1,149
  • 15
  • 16
  • 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). – rawpower Mar 04 '19 at 13:37
7

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).

Mark Z.
  • 2,127
  • 16
  • 33
  • Thanks for this, couldn't get modules working for webpack.config.js but happy to use TypeScript instead which does work. – Paul Watson Feb 12 '20 at 15:00
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.

  • Spectacular - was just looking at Electron and starting up a separate server, your answer helped perfectly! :) – Matt Aug 22 '18 at 20:10
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.

Peter Tseng
  • 13,613
  • 4
  • 67
  • 57
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"

Dylan Stewart
  • 403
  • 4
  • 7
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

stormwild
  • 2,855
  • 2
  • 31
  • 38
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

Farhan Ansari
  • 279
  • 2
  • 14
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

Karol Dowbecki
  • 43,645
  • 9
  • 78
  • 111
andrew I.
  • 19
  • 2
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
Kirti Chaturvedi
  • 1,245
  • 13
  • 24
0

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

Charles Chiakwa
  • 184
  • 1
  • 8
-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

ShortFuse
  • 5,970
  • 3
  • 36
  • 36