require('node-fetch') gives ERR_REQUIRE_ESM
Asked Answered
R

7

87

I just use

const fetch = require('node-fetch')

And I get

Error [ERR_REQUIRE_ESM]: require() of ES Module C:\Users\Alex\Desktop\rollbot\node_modules\node-fetch\src\index.js from C:\Users\Alex\Desktop\rollbot\index.js not supported.
Instead change the require of C:\Users\Alex\Desktop\rollbot\node_modules\node-fetch\src\index.js in C:\Users\Alex\Desktop\rollbot\index.js to a 
dynamic import() which is available in all CommonJS modules.
{
  code: 'ERR_REQUIRE_ESM'
}

All my other packages work, just node-fetch does this. What should I do in order to use node-fetch?

Ranunculus answered 7/9, 2021 at 11:19 Comment(0)
I
67

From the node-fetch package readme:

node-fetch is an ESM-only module - you are not able to import it with require. We recommend you stay on v2 which is built with CommonJS unless you use ESM yourself. We will continue to publish critical bug fixes for it.

If you want to require it, then downgrade to v2.

The other option you have is to use async import('node-fetch').then(...)

Isham answered 7/9, 2021 at 11:24 Comment(3)
Or better use Axios, really a lot of confusion because of ES, CommonJs, and also typescript configs.Enzymolysis
Install the second version: npm install node-fetch@2Rugen
With yarn it should be yarn add node-fetch@2.Kathrynekathy
A
116

What I found is that the latest version of node-fetch changed to ES modules by default. You can:

  1. Uninstall the current version of node-fetch with npm uninstall node-fetch
  2. Install the second version: npm install node-fetch@2

It has worked for me!

Admixture answered 30/1, 2022 at 18:1 Comment(4)
god bless you and blessed be the womb that brought you forth.Mechanist
Thank you so much, I was getting error for octokit and your solution is fixed it.Terrilynterrine
the version 2 just didRackety
This is perfectly worked and Thank youMeeks
I
67

From the node-fetch package readme:

node-fetch is an ESM-only module - you are not able to import it with require. We recommend you stay on v2 which is built with CommonJS unless you use ESM yourself. We will continue to publish critical bug fixes for it.

If you want to require it, then downgrade to v2.

The other option you have is to use async import('node-fetch').then(...)

Isham answered 7/9, 2021 at 11:24 Comment(3)
Or better use Axios, really a lot of confusion because of ES, CommonJs, and also typescript configs.Enzymolysis
Install the second version: npm install node-fetch@2Rugen
With yarn it should be yarn add node-fetch@2.Kathrynekathy
L
43

LATEST UPDATE MAY 2022

You may not needed node-fetch anymore.

In the latest version of Node.js (18.0.0), global fetch (experimental) is enabled by default.

const res = await fetch('https://nodejs.org/api/documentation.json');
if (res.ok) {
  const data = await res.json();
  console.log(data);
}

Through this addition, the following globals are made available: fetch, FormData, Headers, Request, Response.

You may disable this API with the --no-experimental-fetch command-line flag.

Lesley answered 11/5, 2022 at 3:25 Comment(0)
E
26

In my case, I personally found it easier to require ('cross-fetch') instead. The documentation is here: cross-fetch

It can be used in CommonJS as well as ES6 modules.

Ethe answered 1/10, 2021 at 19:25 Comment(5)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Bohlin
I was trying to use node-fetch with typescript and using cross-fetch worked without any hiccups.Oisin
This is the answer. I wasted too much time with trying to make node-fetch work (v2 doesn't have typescript types, v3 work only in ESM which is not well suported in TS in node.js yet, ugh...). cross-fetch just works.Servomechanical
Read the docs: How does cross-fetch work? (...) If you're in node, it delivers you the node-fetch library. It uses node-fetch v2, so you should just downgrade node-fetch instead of adding another unnecessary dependency layer.Triable
cross-fetch works only over httpSKirby
B
8

You can use node-fetch@3 from CommonJS using dynamic imports. Since fetch is already an async API you can define a wrapper like this:

fetch.js

exports.fetch = async function (url, init) {
    const {default: fetch} = await import("node-fetch");
    return await fetch(url, init);
};

You can then use the wrapper like this:

const fetch = require("./fetch");

This trick doesn't work out of the box in TypeScript since TypeScript transforms the dynamic import to a regular require. To work around this just add the plain fetch.js to your project and also add a type declaration:

fetch.d.ts

/**
 * @param { import("node-fetch").RequestInfo} url
 * @param {import("node-fetch").RequestInit} init
 * @returns {Promise<import("node-fetch").Response>}
 */
export function fetch(
    url: import("node-fetch").RequestInfo,
    init: import("node-fetch").RequestInit
): Promise<import("node-fetch").Response>;

cross-fetch is a nice alternative but it's wrapping a 2.x version of node-fetch so you won't get the latest version.

Bombsight answered 12/8, 2022 at 7:59 Comment(0)
M
4

NodeJS supports two different module types:

  • the original CommonJS module that uses require() to load other modules
  • the newer ECMAScript modules (aka ESM) that use import to load other modules.

As mentioned in node-fetch changelog (28 Aug 2021):

This module was converted to be a ESM only package in version 3.0.0-beta.10. node-fetch is an ESM-only module — you are not able to import it with require. We recommend you stay on v2 which is built with CommonJS unless you use ESM yourself. We will continue to publish critical bug fixes for it.

Alternatively, you can use the async import() function from CommonJS to load node-fetch asynchronously:

const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));

So, you can use this one-liner instead of const fetch = require('node-fetch').

Or instead of trying to load node-fetch, you can install and load the module node-fetch-commonjs instead. It's a CommonJS wrapper around node-fetch that should provide you compatibility:

const fetch = require('node-fetch-commonjs')
Marijuana answered 24/12, 2022 at 17:56 Comment(0)
S
0

https://github.com/alex-kinokon/esm-hook worked nicely for me. Require it before you try to import node-fetch. Either via --require or at the top of your script.

Solidus answered 15/9, 2022 at 16:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.