node-fetch 3.0.0 和 jest 给出 SyntaxError: Cannot use import statements Outside a module

ave*_*mia 35 javascript node.js typescript jestjs node-fetch

我正在尝试升级我的 api 以使用 node-fetch 3.0.0。他们的文档中的部分重大更改是,node-fetch 现在是一个纯粹的 ESM 模块。

\n

https://github.com/node-fetch/node-fetch/blob/main/docs/CHANGELOG.md

\n

我的单元测试已经开始突破这个变化。我使用 jest.requireActual("node-fetch") 作为 Response 对象

\n
const { Response } = jest.requireActual("node-fetch");\n
Run Code Online (Sandbox Code Playgroud)\n

然而,随着新的变化,我得到:

\n

“类型 \'{}\' 上不存在属性 \'Response\'。”

\n

我尝试更改为 import 语句,这似乎可以修复该错误:

\n
import { Response } from "node-fetch"\n
Run Code Online (Sandbox Code Playgroud)\n

现在,当我运行单元测试时,出现以下错误:

\n
Test suite failed to run\n                                                                                                                                                                                                                                                                                                                                                                                         \n    Jest encountered an unexpected token                                                                                                                                                                                                                                                                                                                                                 \n                                                                                                                                                                                                                                                                                                                                                                                         \n    This usually means that you are trying to import a file which Jest cannot parse, e.g. it\'s not plain JavaScript.                                                                                                                                                                                                                                                                     \n                                                                                                                                                                                                                                                                                                                                                                                         \n    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".                                                                                                                                                                                                                                                                          \n\n    Here\'s what you can do:\n     \xe2\x80\xa2 If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.\n     \xe2\x80\xa2 To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.\n     \xe2\x80\xa2 If you need a custom transformation specify a "transform" option in your config.\n     \xe2\x80\xa2 If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.\n\n    You\'ll find more details and examples of these config options in the docs:\n    https://jestjs.io/docs/en/configuration.html\n\n    Details:\n\n    C:\\Users\\{mypath}\\api\\node_modules\\node-fetch\\src\\index.js:9\n    import http from \'http\';\n    ^^^^^^\n\n    SyntaxError: Cannot use import statement outside a module\n\n      2 | import { AuthProvider, TokenCache } from "./tokenTypes";\n      3 | import { getUserEmail, getUserId, getUserRole } from "../common/authUtil";\n    > 4 | import fetch from "node-fetch";\n
Run Code Online (Sandbox Code Playgroud)\n

该错误似乎发生在节点获取本身内。

\n

我尝试更改 package.json 中的测试脚本以匹配 jest 文档对 ESM 模块的建议。https://jestjs.io/docs/ecmascript-modules

\n

包.json

\n
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"\n
Run Code Online (Sandbox Code Playgroud)\n

该文档还建议更改 jest.config.js 中的转换属性以采用空对象,但对于 typescript 和 ts-jest,我的转换对象如下所示:

\n

笑话配置.js

\n
transform: { "^.+\\\\.ts?$": "ts-jest" }\n
Run Code Online (Sandbox Code Playgroud)\n

如果我将其更改为空对象,我的所有测试都会失败。我对 CJS 与 ESM 不太熟悉,所以任何帮助将不胜感激。

\n

小智 13

Fetch 3.0 旨在使用 esmodules 而不是 commonjs。因此,您必须确保将其导入模块中。

例如:将其导入到 app.js 中:在 package.json 中添加 "type":"module" ,然后导入它。

为了将其导入到其他文件或 app.js 中,您还可以将扩展名从 .js 更改为 mjs,这将告诉 nodejs 将其视为 esmodule。

否则,降级 fetch 以使用支持 commonjs 的旧版本,例如 2.something。

npm install node-fetch@2
npm install @types/node-fetch@2
Run Code Online (Sandbox Code Playgroud)

  • 这不是解决问题的办法 (5认同)