Andrew Bullock
Andrew Bullock

Reputation: 37436

Webpack 5 and ESM

I think I've read every thread on SO and every related page on the internet on this, everything has some variation of a problem

I want:

Node 14 allegedly supports ESM, so lets use that

Setup 1

I have "type": "module" in my package.json

then my webpack.config.js looks something like:


import { somethingUseful } from './src/js/useful-things.js';

export default (env, argv) => {
    return {
        // webpack config here
    };
}

running > webpack (webpack-cli) I get:

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: D:\git\Useroo\webpack.config.js
require() of ES modules is not supported.
require() of webpack.config.js from C:\nvm\v14.14.0\node_modules\webpack-cli\lib\groups\resolveConfig.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename webpack.config.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from package.json.

OK, so lets do what the error message says

Setup 2a

If I remove "type": "module" from my package.json I get

webpack.config.js
import { somethingUseful } from './src/js/useful-things.js';
^^^^^^

SyntaxError: Cannot use import statement outside a module

right.... So lets try the other suggested alternative:

Setup 2b

module.exports = async (env, argv) => {

    var somethingUseful = await import('./src/js/useful-things.js');

    return {
        // webpack config here
    };
}

I get a segfault.

/c/Program Files/nodejs/webpack: line 14: 14272 Segmentation fault "$basedir/node" "$basedir/node_modules/webpack/bin/webpack.js" "$@"

Upvotes: 15

Views: 31597

Answers (3)

Tate Thurston
Tate Thurston

Reputation: 4660

As of version 4.5.0, webpack-cli now supports ES Modules. All that is required is

  • adding "type": "module" to your package.json

or

  • name your webpack config with the mjs extension: webpack.config.mjs

Upvotes: 23

Coderer
Coderer

Reputation: 27314

Webpack does not have native support for ESM config files, as the other answer states, but it does support automatically transpiling them. If your config file is named webpack(.whatever).babel.js, and you have babel properly installed, your config file will be quietly downleveled before use.

As far as I know, the only way to configure Babel in this case is to use a top level .babelrc in your project directory. Mine simply contains {"presets": ["@babel/preset-env"]}. It does mean that if I want to use Babel in the build, I have to configure it through e.g. plugin options, but it works for me.

ETA: user @bendwarn says in a deleted comment that as of Webpack CLI 4.5.0 you can name your config file webpack.config.mjs or just call it webpack.config.js if your package is type: "module" and it should work natively. I haven't tried it (and frankly that second one sounds like a terrible idea).

Upvotes: 1

Andrew Bullock
Andrew Bullock

Reputation: 37436

At the time of writing, webpack-cli just doesn't support ES6 modules, so you basically have to re-implement it yourself.

It's not that hard really, just annoying. You need something like this (simplified for brevity): Just RTFM here https://webpack.js.org/api/node/

import webpack from 'webpack';
import webpackConfig from './webpack.config.js';


var config = await webpackConfig(mode);
var compiler = webpack(config);

compiler.watch()

Upvotes: 4

Related Questions