Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Enhancement]: Error [ERR_REQUIRE_ESM]: Must use import to load ES Module #1622

Closed
naliferov opened this issue Jun 6, 2020 · 28 comments · Fixed by #2381
Closed

[Enhancement]: Error [ERR_REQUIRE_ESM]: Must use import to load ES Module #1622

naliferov opened this issue Jun 6, 2020 · 28 comments · Fixed by #2381

Comments

@naliferov
Copy link

system: macOS
node version: 14.2
[email protected]
[email protected]

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?

@naliferov
Copy link
Author

I already provide this information above: "in package.json i have "type": "module""

@sokra sokra transferred this issue from webpack/webpack Jun 6, 2020
@Legends
Copy link
Member

Legends commented Jun 6, 2020

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

@ogonkov
Copy link

ogonkov commented Jul 9, 2020

When webpack config got .cjs it doesn't seem recognized as valid config at all (file exist).

[webpack-cli] Configuration webpack.config.cjs not found in /Users/user/Projects/project/webpack.config.cjs

@rockerBOO
Copy link

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.

@evenstensberg evenstensberg changed the title Error [ERR_REQUIRE_ESM]: Must use import to load ES Module [Enhancement]: Error [ERR_REQUIRE_ESM]: Must use import to load ES Module Aug 28, 2020
@naliferov
Copy link
Author

This is absolutely madness

@thSoft
Copy link

thSoft commented Sep 17, 2020

Unfortunately @rockerBOO's solution does not work for me, the following error occurs: #1274

@rockerBOO
Copy link

rockerBOO commented Sep 17, 2020

@thSoft I have had success with using the esm plugin. https://www.npmjs.com/package/esm

yarn webpack-dev-server --config ./webpack.config.cjs -r esm

Note: esm module presents a custom module loader that doesn't reflect node ES modules properly. I would take the time to learn of the differences (try to get thing requiring properly in node with modules).

Biggest to note is a lack of named exports in node modules. https://github.com/nodejs/node/blob/master/doc/api/esm.md

@clshortfuse
Copy link

clshortfuse commented Oct 3, 2020

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.

@worc
Copy link

worc commented Nov 5, 2020

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"

webpack/webpack-dev-server#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?

@alexander-akait
Copy link
Member

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

lubieowoce added a commit to lubieowoce/reservise-web that referenced this issue Nov 8, 2020
@trusktr
Copy link

trusktr commented Nov 29, 2020

SyntaxError: Cannot use import statement outside a module

The manual, in case it helps: https://nodejs.org/docs/latest/api/esm.html

@trusktr
Copy link

trusktr commented Nov 29, 2020

@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 #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?

@elsasslegend
Copy link

Having the same issue.
All closed issues relative to this problem reference the workaround quoted here.
But that workaround throws error [ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING]: A dynamic import callback was not specified. as stated by @trusktr
For now we just cannot use mjs modules in our app, although they are officially supported by node since version 13.

@alexander-akait
Copy link
Member

alexander-akait commented Dec 31, 2020

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

@alexander-akait
Copy link
Member

@snoack
Copy link

snoack commented Jan 16, 2021

If I understand correctly v8-compile-cache is a package that webpack explicitly uses. Couldn't you just not use it if an ESM configuration is used?

@alexander-akait
Copy link
Member

@snoack Unfortunately not, no API to disable it

@snoack
Copy link

snoack commented Jan 18, 2021

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

@alexander-akait
Copy link
Member

@snoack it work only before require('v8-compile-cache'), so it works only for whole process

@justsml
Copy link

justsml commented Jan 25, 2021

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. 🤷 👀

@alexander-akait
Copy link
Member

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

@thernstig
Copy link

thernstig commented May 26, 2021

Using the latest webpack 4 and latest webpack 4 dev server (we cannot update to webpack 5 yet) I tried this workaround:

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

It ran me into the ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING error.
I then added the DISABLE_V8_COMPILE_CACHE=1 workaround.

But then I get this error: Error: Cannot find module 'webpack-cli/bin/config-yargs

So I "almost" came all the way, but got stuck there. Is there nothing I can do about it to make it work with Webpack 4 then?

@alexander-akait
Copy link
Member

What is webpack-cli version?

@thernstig
Copy link

I was using these versions of all Webpack related packages:

    "webpack": "4.44.2",
    "webpack-cli": "4.7.0",
    "webpack-dev-server": "3.10.3",
    "webpack-merge": "4.2.2"

@alexander-akait
Copy link
Member

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

@its-dibo
Copy link

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.

@nyngwang

This comment was marked as outdated.

@clshortfuse
Copy link

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

#2381

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.