webpack-cli: [Enhancement]: Error [ERR_REQUIRE_ESM]: Must use import to load ES Module

system: macOS node version: 14.2 webpack@4.43.0 webpack-cli@3.3.11

So, i have config file “webpack.config.js” export default { entry: './i.js', output: { filename: 'bundle.js' } }

in package.json i have “type”: “module”

in i.js i have code

import * as path from 'path';
console.log(path);

so i use cmd webpack --config webpack.config.js

and got error:

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /Users/x8core/Projects/anyx-cli/webpack.config.js
require() of ES modules is not supported.

In documentation i see. “When using webpack to bundle your application, you can pick from a variety of module syntax styles including ES6”

Why i am getting such error? Am i need to use babel?

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 21
  • Comments: 28 (9 by maintainers)

Commits related to this issue

Most upvoted comments

This is absolutely madness

Because you can’t use import inside cjs, please read how it works

This error happens in webpack 4 because it uses require to include your webpack.config.js. When you move to module, webpack is still using require to include your webpack.config.js. Changing the main config to webpack.config.cjs and importing your module inside of that should work.

module.exports = async (env, argv) => {
  const config = await import('./webpack.config.mjs')
  return config.default(env, argv)
}

This uses the function webpack config model but just importing should work.


In the future of webpack 5, webpack-cli 4, there should be native support for .mjs or .js as modules and this “hack” won’t be needed.

So, it’s been a while, but my "type": "module" project works with fine if I rename the .js file to cjs and force --config as a flag.

Previous:

  • webpack --env.target=docs (throws errors)

New:

  • webpack --config webpack.config.cjs --env.target=docs (works)

Not exactly the same thing as supporting a .mjs configuration for Webpack, but at least I don’t have to stop using module packaging for my project.

@nyngwang You’re replying in a issue from mid-2020. It was fixed in webpack-cli 4.5.0 in February 2021 last year. That’s why this is closed.

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

I solved this

ERR_REQUIRE_ESM

by changing the extension of the webpack.config .js to .cjs. It compiles fine, but during runtime I get:

ReferenceError: window is not defined

I tracked it down to the dynamic import: import("./lazy.js") in main.js. If I change it to a normal import the app runs flawlessly.

Here is the repo to reproduce this issue.

Node -v: v14.4.0 Win10

I see, put it in todo, we should fix compatibility with ES in near future, problem in v8-compile-cache 😞

Would process.env.DISABLE_V8_COMPILE_CACHE = '1' work?

just tried the rename and flag workaround and it doesn’t work for me, i get SyntaxError: Cannot use import statement outside a module

it might be a version issue? i’ve got a mix here that i’ve carried over from older projects:

    "webpack": "^5.3.2",
    "webpack-bundle-analyzer": "^3.9.0",
    "webpack-cli": "^3.3.12",
    "webpack-dev-server": "^3.11.0"

moving everything to latest, i get a repeat of an older issue: Error: Cannot find module 'webpack-cli/bin/config-yargs'

    "webpack": "^5.4.0",
    "webpack-bundle-analyzer": "^3.9.0",
    "webpack-cli": "^4.2.0",
    "webpack-dev-server": "^3.11.0"

https://github.com/webpack/webpack-dev-server/issues/2029

but if i change my startup script from the old style to the new:

    "start:old": "cross-env NODE_ENV=development webpack-dev-server --hot --inline --config webpack.config.cjs",
    "start:new": "cross-env NODE_ENV=development webpack serve --hot --inline --config webpack.config.cjs",

i end up back where i started: SyntaxError: Cannot use import statement outside a module

it’s not clear where i should go from here. the older style is incompatible with wherever the config-yargs directory was yeeted off to. the newer style is incompatible with import/export statements?

Unfortunately @rockerBOO’s solution does not work for me, the following error occurs: https://github.com/webpack/webpack-cli/issues/1274

I got this error with webpack -c weback.config.ts

(node:3580) UnhandledPromiseRejectionWarning: Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /workspace/dibo/projects/ngx-cms/node_modules/colorette/index.js
require() of ES modules is not supported.
require() of /workspace/dibo/projects/ngx-cms/node_modules/colorette/index.js from /workspace/dibo/projects/ngx-cms/node_modules/webpack-cli/lib/utils/index.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 /workspace/dibo/projects/ngx-cms/node_modules/colorette/index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /workspace/dibo/projects/ngx-cms/node_modules/colorette/package.json.

    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1089:13)
    at Module.load (internal/modules/cjs/loader.js:937:32)
    at Function.Module._load (internal/modules/cjs/loader.js:778:12)
    at Module.require (internal/modules/cjs/loader.js:961:19)
    at require (/workspace/dibo/projects/ngx-cms/node_modules/v8-compile-cache/v8-compile-cache.js:159:20)
    at Object.get colors [as colors] (/workspace/dibo/projects/ngx-cms/node_modules/webpack-cli/lib/utils/index.js:3:16)
    at Object.error (/workspace/dibo/projects/ngx-cms/node_modules/webpack-cli/lib/utils/logger.js:5:58)
    at runCLI (/workspace/dibo/projects/ngx-cms/node_modules/webpack-cli/lib/bootstrap.js:13:22)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:3580) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:3580) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Found solution, some hacky, but works fine, but no v8 cache for config files, but v8 already cache ES modules, so nothing bad

I know this isn’t a solution for everyone, but my workaround was to change my package.json’s "type" from "module" to "commonjs".

I’m transforming it into ESM as a post-build hack. 🤷 👀

Solved on our side, but there is bug in v8-compile-cache, anyway you can use DISABLE_V8_COMPILE_CACHE webpack --config ./webpack.config.mjs and all will work fine

@clshortfuse You suggestion isn’t working with the latest Webpack (I think).

This is my config:

// webpack.config.cjs
module.exports = async function () {
    return (await import("./webpack.config.mjs")).default;
};
// webpack.config.mjs
import path from "path";

export default {
    entry: "./dist/main.js",
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: "bundle.js",
    },
};

All fine, the config looks good. Now when I run webpack I get an error:

❯ npx webpack -c webpack.config.cjs
[webpack-cli] TypeError [ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING]: A dynamic import callback was not specified.
    at exports.importModuleDynamicallyCallback (internal/process/esm_loader.js:34:9)
    at module.exports (/home/trusktr/src/JomoPipi+nunisynthv2/webpack.config.cjs:4:5)
    at /home/trusktr/src/JomoPipi+nunisynthv2/node_modules/webpack-cli/lib/groups/resolveConfig.js:176:35
    at Array.map (<anonymous>)
    at finalize (/home/trusktr/src/JomoPipi+nunisynthv2/node_modules/webpack-cli/lib/groups/resolveConfig.js:166:20)
    at /home/trusktr/src/JomoPipi+nunisynthv2/node_modules/webpack-cli/lib/groups/resolveConfig.js:101:20
    at Array.map (<anonymous>)
    at resolveConfigFiles (/home/trusktr/src/JomoPipi+nunisynthv2/node_modules/webpack-cli/lib/groups/resolveConfig.js:89:41)
    at module.exports (/home/trusktr/src/JomoPipi+nunisynthv2/node_modules/webpack-cli/lib/groups/resolveConfig.js:247:11)
    at WebpackCLI._baseResolver (/home/trusktr/src/JomoPipi+nunisynthv2/node_modules/webpack-cli/lib/webpack-cli.js:53:38) {
  code: 'ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING'
}

looks like the latest webpack is running the config file through a custom VM, and not providing the needed ESM callback.

EDIT: Looks like this issue was already described in https://github.com/webpack/webpack-cli/issues/1274 and that was closed in favor of this issue.

Why does Webpack run configs through a VM? Trying to prevent people from hacking on Webpack internals at runtime?