【问题标题】:Running js tests - getting "Cannot use import statement outside of a module"运行 js 测试 - 得到“不能在模块外使用 import 语句”
【发布时间】:2020-11-15 07:22:28
【问题描述】:

我添加了type: module,但这没有帮助。

我正在尝试运行对源文件使用 importexport 的 mocha 或 jest 测试。

有关此问题的现有问题的具体细节与我的不同,我也发现对于我的具体情况的人来说,他们难以理解,特别是因为我已经制定了一个具体的答案,其细节与现有问题无关,但与和我一样的人。

【问题讨论】:

  • 再次,您没有在问题中提供足够的信息来获得您所写的答案。 Self-answered questions 还需要满足基本要求。

标签: javascript jestjs mocha.js babeljs


【解决方案1】:

过去,如果不使用 Babel 转译代码,就无法在 Node 中使用 ES 模块(即import/export)。然而,Node 中对 ES 模块的支持现在已经成为现实,而且 Jest 和 Mocha 最近也都添加了对原生使用 ES 模块的支持。

然而,不仅仅是将"type": "module" 添加到您的package.json 中。

在 Jest 中使用原生 ES 模块的步骤

  1. 如前所述,将"type": "module" 添加到您的package.json

  2. jest-environment-nodejest-environment-jsdom-sixteen 安装到您的开发依赖项。例如:

    $ npm i -D jest-environment-node
    
  3. 更新 package.json 中的 Jest 配置并添加 testEnvironment 设置。例如:

    "jest": {
        "testEnvironment": "jest-environment-jsdom-node"
    }
    
  4. 如果您使用的是早于 13.2 的 Node 版本,则在运行 Node 时需要添加两个附加标志:--experimental-modulesexperimental-vm-modules。我使用npx 来执行命令,虽然有点冗长:

    $ npx --node-arg=--experimental-modules --node-arg=--experimental-vm-modules jest
    

这将使用适当的节点标志运行所有 Jest 测试。我建议您在package.json 中将此作为您的test 脚本,如果这是您要这样做的话。

现在你应该可以在没有 Babel 的情况下使用 import/export

最后一点很重要:在 Node 中使用原生 ES 模块时,您必须使用本地模块的整个导入路径,包括文件扩展名。例如:

import lib from "./my/lib.js"

这里是关于原生 ES 模块的 Node 文档,如果您想更详细地了解这一点:https://nodejs.org/dist/latest-v14.x/docs/api/esm.html

我还建议阅读这个 Github 问题,以了解有关本机 ES 模块的 Jest 实现的更多详细信息:https://github.com/facebook/jest/issues/9430

【讨论】:

  • +400(我的赏金)从新贡献者那里得到一个好的答案。欢迎 !!!我很高兴能用我的声望点数欢迎你。
  • 另外,对于使用 14.x 版本 Node 的用户,您只需要--node-arg=--experimental-vm-modules--node-arg=--experimental-modules 不是必需的。
【解决方案2】:

根据the Jest documentation,如果您确保已安装babel-jest,并在配置文件或package.json 中根据the Babel documentation 提供您的Babel 配置,例如:

.babelrc.json

{
  "presets": [
    "@babel/env"
  ]
}

然后babel-jest 将自动获取它,您无需显式地预先构建文件来测试它们。这也意味着你在调用 Babel 时不必在命令行上设置标志。


请注意,如果您确实想要明确预构建,我建议:

  1. 使用pre<script> 脚本而不是在一行中包含多个步骤;和
  2. 重复使用 build 脚本,因此您不必在两个地方进行更改。

在你的情况下:

"scripts": {
  "build": "babel src/ --out-dir lib",
  "pretest": "npm run build",
  "test": "jest lib/*.test.js"
}

【讨论】:

【解决方案3】:

您需要使用编译器,然后在运行测试时使用编译后的文件。

许多参考资料说要添加type: module,但不要多说。
需要明确的是,基本信息:

SyntaxError: Cannot use import statement outside a module

是因为您使用的是import/export 并且您正试图直接运行文件而不进行编译。

这里的思维转变是习惯于在一个目录中编辑文件并在另一个目录中运行测试。或者,一些解决方案提供“飞行中”编译,所以这个细节基本上是隐藏的,只使用源文件。

根据具体需求,有几种不同的方法可以做到这一点。这是迄今为止我发现的最简单的方法之一,使用 Babel 进行编译步骤:

  • 安装 babel npm install babel --save-dev
  • package.json脚本中添加babel命令,例如:

    "scripts": {
      "test": "babel src/ --out-dir lib --presets=@babel/env; jest lib/*.test.js",
      "build": "babel src/ --out-dir lib --presets=@babel/env"
    },  // this was for jest but you can use mocha, etc as needed
        // Note that using preset this way eliminates the need for a specific .babel.config.json file
    

现在,如果你运行:

jest .

你会得到SyntaxError: Cannot use import statement outside a module,但如果你运行npm t,你会得到

Successfully compiled 2 files with Babel.
 PASS  lib/app.test.js
  All tests
    ✓ Canary test (2ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total

接下来,请记住:

  • 编辑src/中的文件
  • lib/ 中运行测试

【讨论】:

    猜你喜欢
    • 2020-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-09
    • 2020-01-27
    相关资源
    最近更新 更多