Whisher
Whisher

Reputation: 32806

How can I use ES6 in webpack.config.js?

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.

Upvotes: 267

Views: 136964

Answers (19)

NeoZoom.lua
NeoZoom.lua

Reputation: 2921

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.

Upvotes: 20

Ironluca
Ironluca

Reputation: 3782

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://stackoverflow.com/questions/41289200/output-an-es-module-using-webpack
  experiments: {outputModule: true},

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

    //Refer: https://stackoverflow.com/questions/41289200/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.

Upvotes: 1

Charles Chiakwa
Charles Chiakwa

Reputation: 324

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

Upvotes: 0

ShortFuse
ShortFuse

Reputation: 6824

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

Upvotes: -3

smac89
smac89

Reputation: 43234

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.

Upvotes: 17

Kirti Chaturvedi
Kirti Chaturvedi

Reputation: 1325

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

Upvotes: 0

stormwild
stormwild

Reputation: 2955

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

Upvotes: 2

Mark Z.
Mark Z.

Reputation: 2447

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

Upvotes: 8

keemor
keemor

Reputation: 1279

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'
        },

Upvotes: 7

andrew I.
andrew I.

Reputation: 19

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

Upvotes: 1

alexb
alexb

Reputation: 908

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.

Upvotes: 21

Edo
Edo

Reputation: 3501

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 }],
        ],
    },
},

Upvotes: 15

Dylan Stewart
Dylan Stewart

Reputation: 403

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"

Upvotes: 2

Dmitry Minkovsky
Dmitry Minkovsky

Reputation: 38203

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

Upvotes: 13

Peter Tseng
Peter Tseng

Reputation: 14003

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.

Upvotes: 3

Farhan Ansari
Farhan Ansari

Reputation: 299

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

Upvotes: 1

Dmitry Glinyanov
Dmitry Glinyanov

Reputation: 59

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.

Upvotes: 5

Konstantin Tarkus
Konstantin Tarkus

Reputation: 38428

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:

Upvotes: 45

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.

Upvotes: 253

Related Questions