node-fetch 3.0.0 和 jest 给出 SyntaxError: Cannot use import statement outside a module

Posted

技术标签:

【中文标题】node-fetch 3.0.0 和 jest 给出 SyntaxError: Cannot use import statement outside a module【英文标题】:node-fetch 3.0.0 and jest gives SyntaxError: Cannot use import statement outside a module 【发布时间】:2021-11-21 18:45:29 【问题描述】:

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

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

我的单元测试已经开始摆脱这种变化。我使用 jest.requireActual("node-fetch") 作为响应对象

const  Response  = jest.requireActual("node-fetch");

但是,随着新的变化,我得到:

“类型‘’上不存在属性‘响应’。”

我尝试更改为似乎可以修复该错误的导入语句:

import  Response  from "node-fetch"

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

Test suite failed to run
                                                                                                                                                                                                                                                                                                                                                                                         
    Jest encountered an unexpected token                                                                                                                                                                                                                                                                                                                                                 
                                                                                                                                                                                                                                                                                                                                                                                         
    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain javascript.                                                                                                                                                                                                                                                                     
                                                                                                                                                                                                                                                                                                                                                                                         
    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".                                                                                                                                                                                                                                                                          

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    C:\Users\mypath\api\node_modules\node-fetch\src\index.js:9
    import http from 'http';
    ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      2 | import  AuthProvider, TokenCache  from "./tokenTypes";
      3 | import  getUserEmail, getUserId, getUserRole  from "../common/authUtil";
    > 4 | import fetch from "node-fetch";

该错误似乎发生在 node-fetch 本身内。

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

package.json

"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js"

该文档还建议更改 jest.config.js 中的 transform 属性以获取一个空对象,但是对于 typescript 和 ts-jest,我的 transform 对象如下所示:

jest.config.js

transform:  "^.+\\.ts?$": "ts-jest" 

如果我将其更改为空对象,我的所有测试都会中断。我对 CJS 与 ESM 不是很熟悉,因此我们将不胜感激。

【问题讨论】:

【参考方案1】:

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

【讨论】:

我添加了 "type":"module" 并将我的 jest.config.js 更改为 "export default" 而不是 module.export。我仍然收到以下错误。 “从'http'导入http;^^^^^^`语法错误:不能在模块外使用导入语句1 | import jest from "@jest/globals"; > 2 | import Response from "node-fetch “;”与4 | import fetch from "node-fetch"; 相同【参考方案2】:

我遇到了同样的问题! 添加

 transform: 
    "^.+\\.(ts|tsx)$": "ts-jest",
    "^.+\\.(js)$": "babel-jest",
  ,
  transformIgnorePatterns: [
  ],

到我的jest.config.js 文件解决了它。 顺便说一句,这些是我的版本:

    "jest": "^27.3.1",
    "ts-jest": "^27.0.7",
    "node-fetch": "^3.1.0"

【讨论】:

ts-jest 使用相同的transform 选项,但仍然遇到错误。

以上是关于node-fetch 3.0.0 和 jest 给出 SyntaxError: Cannot use import statement outside a module的主要内容,如果未能解决你的问题,请参考以下文章

将 async-await 与 node-fetch 一起使用不会将响应返回给调用方法

Jest/Enzyme 单元测试:如何将存储传递给使用 redux 4 和 react-redux 6 连接功能的浅层组件

使用 node-fetch 跳过等待时间

如何在 React 中将 props 传递给 jest 测试

如何断言哪个值已传递给 <li> 键属性以与 jest 和 testing-library/react 反应

Node-fetch 不提供正文中页面的所有 HTML