esm
esm copied to clipboard
"Warning: require() of ES modules is not supported" when package.json has "type":"module"
Environment: Node 12.13.1, both Windows 10 and Ubuntu 16
Snippet to reproduce: package.json
{
"dependencies": {
"esm": "*"
},
"private": true,
"type": "module"
}
module.js
export const X = 1;
main.cjs
require = require("esm")(module);
const m = require("./module.js");
console.log(m.X);
Steps to reproduce:
- Save the above three files in the same directory.
-
npm install
-
node main.cjs
Expected: console prints 1
and nothing else.
Actual:
$ node main.cjs
1
(node:8464) Warning: require() of ES modules is not supported.
require() of C:\Users\sunny\Documents\code\esmbug\module.js from C:\Users\sunny\Documents\code\esmbug\main.cjs 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 module.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from C:\Users\sunny\Documents\code\esmbug\package.json.
Observations:
- The program is running fine except for the warning message.
- The warning only appears when the program is running for the first time. It does not reappear, unless
node_modules/.cache
directory is deleted. - Node 12.13.1 is the first time this warning appears; it did not appear in Node 12.13.0.
This is a problem. Indeed v12.13.1 introduced a warning but in v13 it's an exception.
(node:40068) Warning: require() of ES modules is not supported.
require() of ./index.js from ./test/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 ./index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from ./package.json.
Uncaught exception in test/index.js
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: ./index.js
✖ test/index.js exited with a non-zero exit code: 1
1 uncaught exception
I'm using esm
via AVA
Note that this error can be overridden by overwriting the require._extensions['.js']
function in Node.js. The same applies for the similar error when requiring .mjs
files.
The body of the .js
extension function is:
// Native extension for .js
Module._extensions['.js'] = function(module, filename) {
if (filename.endsWith('.js')) {
const pkg = readPackageScope(filename);
// Function require shouldn't be used in ES modules.
if (pkg && pkg.data && pkg.data.type === 'module') {
const parentPath = module.parent && module.parent.filename;
const packageJsonPath = path.resolve(pkg.path, 'package.json');
throw new ERR_REQUIRE_ESM(filename, parentPath, packageJsonPath);
}
}
const content = fs.readFileSync(filename, 'utf8');
module._compile(content, filename);
};
which should be possible to replace in userland in this project with a version without the error.
Ensuring these were overidable was a goal here, so I hope this can solve the use case.
Note that this error can be overridden by overwriting the require._extensions['.js'] function in Node.js.
In case it’s not clear how to implement this 👆, like it was for me, you can use this (which is taken from @guybedford’s example on https://github.com/standard-things/esm/issues/868#issuecomment-594480715):
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);
};
Essentially it’s just the native node code referenced above but without the error for require()
.
By putting this in your root module you should be able to get things working for node >= 12.13.1. 🙌
Note that there’s a PR (#877) to fix this, but the project seems stale so not sure if it will ever be merged. 😕
Use axios instead of fetch.