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

Roo*_*sma 127 javascript node.js node-fetch

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

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

节点版本:

user@MYLLYTIN:~/CAMSERVER$ node -v
v14.17.6
Run Code Online (Sandbox Code Playgroud)

节点获取包版本:

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

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

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

user@MYLLYTIN:~/CAMSERVER$ cat server.js 
import fetch from "node-fetch";
Run Code Online (Sandbox Code Playgroud)

结果:

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

Ren*_*ink 66

来自升级指南

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

或者,您可以使用 CommonJS 中的 async import() 函数来异步加载节点获取:

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

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

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

编辑

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

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

由于您使用的是打字稿,您应该这样做

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

const fetch = (url: RequestInfo, init?: RequestInit) =>  import("node-fetch").then(({ default: fetch }) => fetch(url, init));
Run Code Online (Sandbox Code Playgroud)

  • 由于“import nodeFetch...”语句,它不起作用。您应该只导入类型而不是实现。这应该有效:`import {RequestInfo, RequestInit} from 'node-fetch'; const fetch = (url: RequestInfo, init?: RequestInit) =&gt; import('node-fetch').then(({ default: fetch }) =&gt; fetch(url, init));` (6认同)
  • @JeremyThille 你知道为什么吗?我和你一样 - 我已经在使用 import 了。 (2认同)

And*_*orn 34

为了解决这个问题,我降级node-fetch到最新版本 2,现在是2.6.6. 这是我运行的脚本:

yarn add node-fetch@^2.6.6
Run Code Online (Sandbox Code Playgroud)

或者

npm install node-fetch@^2.6.6
Run Code Online (Sandbox Code Playgroud)

我还添加了这些编译器选项:

{
  "compilerOptions": { "allowJs": true, "outDir": "./dist" },
}
Run Code Online (Sandbox Code Playgroud)

  • 您到底在哪里添加了编译器选项? (3认同)

Geo*_*oth 17

node-fetchv3 仅适用于 ESM: https: //github.com/node-fetch/node-fetch#loading-and-configuring-the-module。您添加的模块esm是为了添加 ESM 兼容性,但现在 Node 12+ 本身就支持 ESM,因此不再需要它;并且\xe2\x80\x99 不能与仅 ESM 的软件包(如node-fetch3+)一起使用。

\n

要解决您的问题:

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

那\xe2\x80\x99就是它。然后当你运行时node server.js它应该可以工作。

\n


Ciz*_*zia 13

我以前的解决方案总是出错,这对我来说每次都有效

npm i -D node-fetch

const _importDynamic = new Function('modulePath', 'return import(modulePath)');

export const fetch = async function (...args: any) {
    const {default: fetch} = await _importDynamic('node-fetch');
    return fetch(...args);
}
Run Code Online (Sandbox Code Playgroud)


GmB*_*dhi 7

使用 ESM 语法,也在运行文件之前使用这些方法之一。

  1. 指定"type":"module"package.json
  2. --input-type=module或者在运行文件时使用此标志
  3. 或者使用.mjs文件扩展名
  4. 否则使用动态加载包import()