错误:导入 node-fetch 时不支持 ES module的 require()

IT技术 javascript node.js node-fetch
2021-02-10 12:51:39

我正在创建一个程序来分析安全摄像头流并卡在第一行。目前我的 .js 文件只有 node-fetch 的导入,它给了我一条错误消息。我究竟做错了什么?

在适用于 Linux 的 Windows 子系统中运行 Ubuntu 20.04.2 LTS。

节点版本:

user@MYLLYTIN:~/CAMSERVER$ node -v
v14.17.6

节点获取包版本:

user@MYLLYTIN:~/CAMSERVER$ npm v node-fetch

node-fetch@3.0.0 | MIT | deps: 2 | versions: 63
A light-weight module that brings Fetch API to node.js
https://github.com/node-fetch/node-fetch

keywords: fetch, http, promise, request, curl, wget, xhr, whatwg

dist
.tarball: https://registry.npmjs.org/node-fetch/-/node-fetch-3.0.0.tgz
.shasum: 79da7146a520036f2c5f644e4a26095f17e411ea
.integrity: sha512-bKMI+C7/T/SPU1lKnbQbwxptpCrG9ashG+VkytmXCPZyuM9jB6VU+hY0oi4lC8LxTtAeWdckNCTa3nrGsAdA3Q==
.unpackedSize: 75.9 kB

dependencies:
data-uri-to-buffer: ^3.0.1 fetch-blob: ^3.1.2         

maintainers:
- endless <jimmy@warting.se>
- bitinn <bitinn@gmail.com>
- timothygu <timothygu99@gmail.com>
- akepinski <npm@kepinski.ch>

dist-tags:
latest: 3.0.0        next: 3.0.0-beta.10  

published 3 days ago by endless <jimmy@warting.se>

esm 包版本:

user@MYLLYTIN:~/CAMSERVER$ npm v esm

esm@3.2.25 | MIT | deps: none | versions: 140
Tomorrow's ECMAScript modules today!
https://github.com/standard-things/esm#readme

keywords: commonjs, ecmascript, export, import, modules, node, require

dist
.tarball: https://registry.npmjs.org/esm/-/esm-3.2.25.tgz
.shasum: 342c18c29d56157688ba5ce31f8431fbb795cc10
.integrity: sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==
.unpackedSize: 308.6 kB

maintainers:
- jdalton <john.david.dalton@gmail.com>

dist-tags:
latest: 3.2.25  

published over a year ago by jdalton <john.david.dalton@gmail.com>

.js 文件的内容(实际上只是导入):

user@MYLLYTIN:~/CAMSERVER$ cat server.js 
import fetch from "node-fetch";

结果:

user@MYLLYTIN:~/CAMSERVER$ node -r esm server.js 
/home/user/CAMSERVER/node_modules/node-fetch/src/index.js:1
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /home/user/CAMSERVER/node_modules/node-fetch/src/index.js
require() of ES modules is not supported.
require() of /home/user/CAMSERVER/node_modules/node-fetch/src/index.js from /home/user/CAMSERVER/server.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 /home/user/CAMSERVER/node_modules/node-fetch/package.json.

    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1089:13) {
  code: 'ERR_REQUIRE_ESM'
}
user@MYLLYTIN:~/CAMSERVER$ 
3个回答

来自升级指南

node-fetch 在3.0.0-beta.10版本中被转换为仅 ESM 的包node-fetch 是一个仅限 ESM 的module - 您无法使用 require 导入它。

或者,您可以使用 CommonJS 中的 async import() 函数来异步加载 node-fetch:

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

或者你像他们在自述文件中所说的那样继续使用v2

node-fetch是一个仅限 ESM 的module - 您不能使用 require 导入它。我们建议您继续使用使用 CommonJS 构建的 v2,除非您自己使用 ESM。我们将继续为它发布关键的错误修复。

编辑

我在文档中看到了,使用了它,脚本崩溃了:

错误 TS2556:展开参数必须具有元组类型或传递给其余参数。

由于您使用的是typescript,因此您应该执行以下操作

import nodeFetch, { RequestInfo, RequestInit } from "node-fetch";

const fetch = (url: RequestInfo, init?: RequestInit) =>  import("node-fetch").then(({ default: fetch }) => nodeFetch(url, init));
@JeremyThille 你有没有发现原因?我和你一样 - 我已经在使用导入了。
2021-03-17 12:51:39
非常感谢你。我确实尝试过,但我得到Error [ERR_REQUIRE_ESM]: Must use import to load ES Module. require() of ES modules is not supported. index.ts 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 node_modules/node-fetch/package.json.它一直说我正在使用require,但我正在使用import. 运行我的 TS 文件ts-node-dev index.ts
2021-03-26 12:51:39
@JeremyThille 我已经更新了我的答案。我还没有测试它,所以请让我知道它是否有效。
2021-04-05 12:51:39
我回滚到 node-fetch v2,但它工作正常。
2021-04-06 12:51:39
我在文档中看到了,使用了它,脚本崩溃了:error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.Node.js 14.17.1
2021-04-11 12:51:39

node-fetchv3 仅支持 ESM:https : //github.com/node-fetch/node-fetch#loading-and-configuring-the-moduleesm您添加module是为了添加 ESM 兼容性,但现在 Node 12+ 原生支持 ESM 是不必要的;它不适用于node-fetch3+等仅限 ESM 的软件包

要解决您的问题:

  1. 取出esm包装。
  2. 添加"type": "module"到您的package.json.

就是这样。然后当你运行node server.js它应该工作。

我认为.mjs在为 Node 编写 ESM 代码时仍然建议使用该扩展,但我找不到参考。
2021-03-24 12:51:39
.mjs是一个选项,但不是必需的。nodejs.org/api/packages.html#determining-module-system
2021-04-04 12:51:39

有几种方法可以做到这一点:

  1. 指定"type":"module"package.json
  2. --input-type=module运行文件时使用此标志
  3. 使用.mjs文件扩展名