Skip to content
This repository has been archived by the owner on Nov 4, 2024. It is now read-only.

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module / require() of ES modules is not supported #868

Open
chrisveness opened this issue Feb 13, 2020 · 25 comments

Comments

@chrisveness
Copy link

chrisveness commented Feb 13, 2020

I have suddenly started getting the following error:

$ npm test

> geodesy@2.2.0 test /home/travis/build/chrisveness/geodesy
> mocha --exit -r esm test/*.js

/home/travis/build/chrisveness/geodesy/node_modules/mocha/lib/mocha.js:1
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /home/travis/build/chrisveness/geodesy/test/dms-tests.js
require() of ES modules is not supported.
require() of /home/travis/build/chrisveness/geodesy/test/dms-tests.js from /home/travis/build/chrisveness/geodesy/node_modules/mocha/lib/mocha.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 dms-tests.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /home/travis/build/chrisveness/geodesy/package.json.

    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1167:13)
    at /home/travis/build/chrisveness/geodesy/node_modules/mocha/lib/mocha.js:311:36
    at Array.forEach (<anonymous>)
    at Mocha.loadFiles (/home/travis/build/chrisveness/geodesy/node_modules/mocha/lib/mocha.js:308:14)
    at Mocha.run (/home/travis/build/chrisveness/geodesy/node_modules/mocha/lib/mocha.js:849:10)
    at Object.exports.singleRun (/home/travis/build/chrisveness/geodesy/node_modules/mocha/lib/cli/run-helpers.js:108:16)
    at exports.runMocha (/home/travis/build/chrisveness/geodesy/node_modules/mocha/lib/cli/run-helpers.js:143:13)
    at Object.exports.handler (/home/travis/build/chrisveness/geodesy/node_modules/mocha/lib/cli/run.js:305:3)
    at Object.runCommand (/home/travis/build/chrisveness/geodesy/node_modules/yargs/lib/command.js:242:26)
    at Object.parseArgs [as _parseArgs] (/home/travis/build/chrisveness/geodesy/node_modules/yargs/yargs.js:1087:28)
    at Object.parse (/home/travis/build/chrisveness/geodesy/node_modules/yargs/yargs.js:566:25)
    at Object.exports.main (/home/travis/build/chrisveness/geodesy/node_modules/mocha/lib/cli/cli.js:68:6)
    at Object.<anonymous> (/home/travis/build/chrisveness/geodesy/node_modules/mocha/lib/cli/cli.js:73:11)
    at Generator.next (<anonymous>)
    at internal/main/run_main_module.js:17:47 {
  code: 'ERR_REQUIRE_ESM'
}
npm ERR! Test failed.  See above for more details.

This doesn't make any sense, as I am not using require() anywhere at all.

It seems to be happening with Node.js > v12.12.0, including all v13.

Strangely, it seems that when I get this in my local environment, if I switch to 12.12.0 (using nvm), run tests, then switch back to later versions of Node, then all tests pass successfully (up to and including with v13.8.0).

However, I can't do this for the CI tests: travis-ci.org/chrisveness/geodesy/builds/649986393 (repo: github.com/chrisveness/geodesy.

Is there any way I can git CI tests to run successfully, as I can get local tests to run by switching versions of Node?

Thanks

@azz
Copy link

azz commented Feb 14, 2020

We've just hit this after pulling the latest node:12 docker images. I guess it is introduced in node 12.16.0

@damianobarbati
Copy link

damianobarbati commented Feb 16, 2020

What a mess, on node v12.16.0 all of my projects are now broken :)

This happens because I have in node_modules both:

  • modules without type=module
  • modules with type=module

@jdalton I guess ESM is transpiling both to require/cjs and nodejs is complaining about this because is enforcing the type=module + import syntax now.

EDIT: just reverted to node v12.1.14 where it shows the warning:

(node:7983) Warning: require() of ES modules is not supported.

@uniqname
Copy link

Ran into this problem, but for us, we tracked it down to @babel/runtime and this commit. Reverting to @babel/runtime@7.7.2 resolved the issue for us. It seems that the node v12 revamp of the native esm implementation to match node v13 triggered this, but the implications of this on this package (standard-things/esm) are not clear to me.

@yoursunny
Copy link

This is in fact the same bug as #855. It's an warning in Node 12.15 but becomes an error in Node 12.16.

@guybedford
Copy link

Which version of esm are you getting this error with?

@iippis
Copy link

iippis commented Mar 4, 2020

Which version of esm are you getting this error with?

We are using 3.2.25

@guybedford
Copy link

guybedford commented Mar 4, 2020

Note this error is thrown by the .js extension handler in the CJS loader for Node.js here - https://github.com/nodejs/node/blob/master/lib/internal/modules/cjs/loader.js#L1211.

If someone wants to work on a PR to fix esm, the fix would be to patch the native extensions['.js'] with something like:

const module = require('module');
module.Module._extensions['.js'] = function(module, filename) {
  const content = fs.readFileSync(filename, 'utf8');
  module._compile(content, filename);
};

@kriskowal
Copy link

Would it be possible to switch the behaviors of importing with .js to either .cjs or .mjs depending on the type: module declaration in each package’s package.json?

@glud123
Copy link

glud123 commented Apr 28, 2020

Ran into this problem, but for us, we tracked it down to @babel/runtime and this commit. Reverting to @babel/runtime@7.7.2 resolved the issue for us. It seems that the node v12 revamp of the native esm implementation to match node v13 triggered this, but the implications of this on this package (standard-things/esm) are not clear to me.

Thanks. Downgrade @babel/runtime to 7.7.2 fixed it for me.

@seanCodes
Copy link

I was able to get this working using the extension handler override solution above (thanks @guybedford!! 🙏) with a tweak to require('fs') since that was missing from the original snippet:

const module = require('module');
const fs = require('fs');
module.Module._extensions['.js'] = function (module, filename) {
  const contents = fs.readFileSync(filename, 'utf8');
  module._compile(require('fs').readFileSync(filename, 'utf8'), filename);
};

or if you’re willing to sacrifice code clarity for something more condensed:

require('module').Module._extensions['.js'] = function (module, filename) { 
  module._compile(require('fs').readFileSync(filename, 'utf8'), filename);
};

For purists, it’s worth mentioning that this can be used with ES module syntax too.

import { readFileSync } from 'fs';
import module from 'module';

module.Module._extensions['.js'] = function (module, filename) {
  module._compile(readFileSync(filename, 'utf8'), filename);
};

Whatever you use, make sure to included it as early as possible in your app. (In my case it was a Vue/Nuxt app so I put it at the top of nuxt.config.js)

@mk-pmb
Copy link
Contributor

mk-pmb commented May 31, 2021

Thanks @guybedford and @seanCodes for your monkey patches. Unfortunately, in my case it just results in

Error: Cannot load module from .mjs: file:///mnt/…/node_modules/is-fn/index.js

albeit I assigend the loader function to both _extensions['.js'] and _extensions['.mjs']. Do you have an ideas what might be missing?

@Venryx
Copy link

Venryx commented Jun 22, 2021

Oh, it looks like Node 14.13.0+ supports named imports from common-js modules!: https://simonplend.com/node-js-now-supports-named-imports-from-commonjs-modules-but-what-does-that-mean

Well, some of them anyway. (the blog post linked shows how it only works for some packages -- ones where cjs-module-lexer is able to detect the export names through static analysis)

There may not be a need for these sorts of workarounds soon then. (I'll have to see, after using Node 14.13.0+ for a while)

@seanCodes
Copy link

seanCodes commented Jun 30, 2021

@mk-pmb According to #851 this seems to be an esm limitation rather than node. The readme has a note:

🔒 .mjs files are limited to basic functionality without support for esm options.

It’s not clear what “basic functionality” is but I suspect that’s why the patch isn’t working in your case.

@mk-pmb
Copy link
Contributor

mk-pmb commented Jul 1, 2021

Thanks for the idea. However I doubt that it's a problem with the esm module, because the same tarball extracted on an ancient Ubuntu with node v8.17.0 works, but breaks on Ubuntu focal with node v12.

That said, I don't understand what "without" means in the quote. Are esm files limited unless support is enabled in the options, or are they limited in that none of the options are supported? Then again, none of both interpretations would explain why it works on node v8.17.0.

@diauweb
Copy link

diauweb commented Oct 11, 2021

Concluding the discussion, this snippet shall work

https://gist.github.com/diauweb/f9f7be271ecc7bc0aecaf3dc891e18d2

@mk-pmb
Copy link
Contributor

mk-pmb commented Oct 17, 2021

Thanks, I'll test it asap. Meanwhile I also found the fix-esm module.

@mk-pmb
Copy link
Contributor

mk-pmb commented Oct 17, 2021

I think I understand the use case now. Your snippet and the fix-esm module both make it possible for a CJS module to synchronously require ESM modules. For that, they work. Thanks!

@brumm
Copy link

brumm commented Dec 1, 2021

I made a reproduction case: https://stackblitz.com/edit/node-fyfxhz?file=main.js

yarn add esm file-icon; node index.js

importing path works, importing file-icon does not. This seems like a pretty big issue and makes it impossible to use esm at all for me.

@jason-henriksen
Copy link

I had a hell of a time with all this. I'm just posting my solution repo, in hopes it helps someone else.

This imports an ESM dependency (ora) into TypeScript without using babel.
https://github.com/jason-henriksen/typescript-with-esm-no-babel-boilerplate

@EarthlingDavey
Copy link

I had a hell of a time with all this.

Oh snap 🤣 So happy to have come across your fork here! TY!

My issue was.. I needed @cfworker/json-schema (+ TS + testing) and spent hours going round in circles with mocha.

Your boilerplate made all my problems disapear 👊💯

@Stusaw
Copy link

Stusaw commented Feb 24, 2022

I am constantly switching node versions (using nvm) to work on different projects. This was the root of my issue and needed to be on v14.0

@devmuhammadnurulahsan
Copy link

const random = require('random');
^

Error [ERR_REQUIRE_ESM]: require() of ES Module F:\All Web Development World\Github-bot\node_modules\random\dist\random.module.js from F:\All Web Development
World\Github-bot\index.js not supported.
Instead change the require of random.module.js in F:\All Web Development World\Github-bot\index.js to a dynamic import() which is available in all CommonJS modules.

@adembacajdev
Copy link

adembacajdev commented Nov 23, 2022

Whoever wants to use both require and import, you only have to add these two lines at the top of your root project (index.js)

import {createRequire} from 'module';
const require = createRequire(import.meta.url);

and in package.json, you have to add

"type": "module"

Hope it works for you

@mk-pmb
Copy link
Contributor

mk-pmb commented Nov 23, 2022

@adembacajdev Glad that it works for you. The problem is that declaring your package as type: module comes at a cost that lots of people don't want to pay.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

No branches or pull requests