esm icon indicating copy to clipboard operation
esm copied to clipboard

"Warning: require() of ES modules is not supported" when package.json has "type":"module"

Open yoursunny opened this issue 5 years ago • 4 comments

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:

  1. Save the above three files in the same directory.
  2. npm install
  3. 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.

yoursunny avatar Nov 22 '19 04:11 yoursunny

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

fregante avatar Nov 25 '19 20:11 fregante

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.

guybedford avatar Dec 18 '19 01:12 guybedford

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

seanCodes avatar Jul 14 '20 05:07 seanCodes

Use axios instead of fetch.

swetasrinaidu avatar Jul 19 '22 12:07 swetasrinaidu