'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:
- To use webpack to bundle my web app up
- To use ES Modules within my source js and have them transpiled down for wider browser support
- To use ES Modules within my webpack configuration
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" "$@"
Solution 1:[1]
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
mjsextension:webpack.config.mjs
Solution 2:[2]
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).
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Coderer |
