require('node-fetch') 给出 ERR_REQUIRE_ESM

Ale*_*scu 82 javascript node.js node-fetch

我只是用

const fetch = require('node-fetch')
Run Code Online (Sandbox Code Playgroud)

我得到

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'
}
Run Code Online (Sandbox Code Playgroud)

我的所有其他包都可以工作,只有 node-fetch 可以做到这一点。为了使用node-fetch,我应该做什么?

小智 108

我发现最新版本node-fetch默认改成了ES模块。你可以:

  1. 卸载当前版本的node-fetchnpm uninstall node-fetch
  2. 安装第二个版本:npm install node-fetch@2

它对我有用!

  • 上帝保佑你,也保佑生下你的子宫。 (4认同)

Kon*_*nev 67

node-fetch 包自述文件

node-fetch 是一个仅限 ESM 的模块 - 您无法使用 require 导入它。我们建议您保留使用 CommonJS 构建的 v2,除非您自己使用 ESM。我们将继续发布重要的错误修复。

如果您愿意require,请降级到 v2。

您的另一个选择是使用异步import('node-fetch').then(...)

  • 或者更好地使用 Axios,由于 ES、CommonJs 以及 typescript 配置,确实造成了很多混乱。 (7认同)
  • 安装第二个版本:npm install node-fetch@2 (5认同)

Moh*_*rif 39

2022 年 5 月最新更新

你可能不再需要了node-fetch

在最新版本Node.js18.0.0)中,默认启用全局获取(实验性)。

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

通过此添加,可以使用以下全局变量:fetch, FormData, Headers, Request, Response.

--no-experimental-fetch 您可以使用命令行标志禁用此 API 。


小智 26

就我而言,我个人发现使用 require ('cross-fetch') 更容易。文档在这里:交叉获取

它可以在 CommonJS 和 ES6 模块中使用。

  • 通过额外的支持信息可以改进您的答案。请[编辑]添加更多详细信息,例如引文或文档,以便其他人可以确认您的答案是正确的。您可以[在帮助中心](/help/how-to-answer)找到有关如何写出好的答案的更多信息。 (2认同)
  • 我试图将节点获取与打字稿结合使用,并且使用交叉获取没有任何问题。 (2认同)

Fab*_*obs 8

您可以node-fetch@3通过动态导入从 CommonJS 中使用。由于 fetch 已经是一个异步 API,你可以像这样定义一个包装器:

fetch.js

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

然后您可以像这样使用包装器:

const fetch = require("./fetch");
Run Code Online (Sandbox Code Playgroud)

这个技巧在 TypeScript 中并不能开箱即用,因为 TypeScript 将动态导入转换为常规需求。要解决此问题,只需将纯文本添加fetch.js到您的项目中,并添加类型声明:

获取.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>;
Run Code Online (Sandbox Code Playgroud)

cross-fetch是一个不错的选择,但它包装了 2.x 版本,node-fetch因此您无法获得最新版本。