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

Improve error message for replacing require usage with dynamic import #40544

Open
fabiancook opened this issue Oct 21, 2021 · 2 comments · May be fixed by #53152
Open

Improve error message for replacing require usage with dynamic import #40544

fabiancook opened this issue Oct 21, 2021 · 2 comments · May be fixed by #53152
Labels
errors Issues and PRs related to JavaScript errors originated in Node.js core. esm Issues and PRs related to the ECMAScript Modules implementation.

Comments

@fabiancook
Copy link
Contributor

fabiancook commented Oct 21, 2021

Version

17.0.1

Platform

Darwin Fabians-Mac-mini-2.local 19.6.0 Darwin Kernel Version 19.6.0: Tue Jan 12 22:13:05 PST 2021; root:xnu-6153.141.16~1/RELEASE_X86_64 x86_64

Subsystem

No response

What steps will reproduce the bug?

package.json:

{
  "type": "module",
  "dependencies": {
    "node-fetch": "3.0.0"
  }
}

index.js:

const fetch = require("node-fetch");
(async function main() {
  const response = await fetch("https://httpbin.org/get");
  const json = await response.json();
  console.log(json);
})();
$ node index.js
const fetch = require("node-fetch");
              ^

ReferenceError: require is not defined in ES module scope, you can use import instead
This file is being treated as an ES module because it has a '.js' file extension and '/Users/fabian/src/reproduce/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.

Direct replacing of require with import (this is an incorrect assumption after looking at the error):

const fetch = import("node-fetch");
(async function main() {
  const response = await fetch("https://httpbin.org/get");
  const json = await response.json();
  console.log(json);
})();
$ node index.js                                                                                                                                                                                                       
file:///Users/fabian/src/reproduce/index.js:3
  const response = await fetch("https://httpbin.org/get");
                         ^

TypeError: fetch is not a function

How often does it reproduce? Is there a required condition?

No response

What is the expected behavior?

Instead the error could say something that includes that the returned value from import must be awaited:

ReferenceError: require is not defined in ES module scope, you can use "const { default: moduleName } = await import('module_name')" instead

Or maybe

ReferenceError: require is not defined in ES module scope, see the documentation for import here: ...

Or even (not directly referencing the import itself, leading users to have to go look at the docs!)

ReferenceError: require is not defined in ES module scope, you can use ES module styled dynamic imports instead

Which the user could interpret directly and make the change:

const { default: fetch } = await import("node-fetch");
(async function main() {
  const response = await fetch("https://httpbin.org/get");
  const json = await response.json();
  console.log(json);
})();
$ node index.js                                                                                                                                                                                                       
(node:86241) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
{
  args: {},
  headers: {
    Accept: '*/*',
    'Accept-Encoding': 'gzip,deflate,br',
    Host: 'httpbin.org',
    'User-Agent': 'node-fetch',
    'X-Amzn-Trace-Id': 'Root=1-6171395b-7b89119e02d2082a34e20d31'
  },
  origin: '103.62.49.195',
  url: 'https://httpbin.org/get'
}

What do you see instead?

No response

Additional information

Picked up from this twitter thread https://twitter.com/jsoverson/status/1450823245146599429

I couldn't see any mention of a specific issue being created from this.

@targos
Copy link
Member

targos commented Oct 21, 2021

const { default: fetch } = await import("node-fetch");

While this works, I don't think it's what we should suggest to the user.
This is what we would like the user to change their require call to:

import fetch from 'node-fetch';

@targos targos added errors Issues and PRs related to JavaScript errors originated in Node.js core. esm Issues and PRs related to the ECMAScript Modules implementation. labels Oct 22, 2021
@fulldecent
Copy link

I also got this error when parsing a local JSON file. Here is the new code I needed to use:

const config = JSON.parse(fs.readFileSync("./config.json"));

DanKaplanSES added a commit to DanKaplanSES/node that referenced this issue May 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
errors Issues and PRs related to JavaScript errors originated in Node.js core. esm Issues and PRs related to the ECMAScript Modules implementation.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants