运行 js 测试 - 获取 "Cannot use import statement outside of a module"
Running js tests - getting "Cannot use import statement outside of a module"
我添加了 type: module
但这没有帮助。
我正在尝试 运行 使用 import
和 export
作为源文件的 mocha 或 jest 测试。
关于此的现有问题具有与我的不同的细节,我也发现对于具有我特定情况的人来说,这些问题令人困惑,特别是因为我已经制定了一个具体的答案,其中的细节与现有问题无关,但是与我处境中的其他人相关。
您需要使用编译器,然后在运行测试时使用编译后的文件。
很多参考文献都说要加type: module
,但不多说了。
明确一点,基本信息:
SyntaxError: Cannot use import statement outside a module
是因为您正在使用 import
/export
并且 您正在尝试直接 运行 文件而无需编译。
这里的思维转变是习惯于在一个目录中编辑文件,运行在另一个目录中进行测试。或者,一些解决方案提供 "in'flight" 编译,因此这个细节基本上是隐藏的,只使用源文件。
根据具体需要,有几种不同的方法可以做到这一点。这是迄今为止我发现的最简单的方法之一,使用 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/
根据 the Jest documentation, if you make sure babel-jest
is installed and supply your Babel configuration per the Babel documentation,在配置文件中或 package.json
例如:
.babelrc.json
{
"presets": [
"@babel/env"
]
}
然后 babel-jest
将自动获取它,您无需显式预构建文件来测试它们。这也意味着您不必在调用 Babel 时在命令行上设置标志。
请注意,如果您确实想要明确预构建,我建议:
- 使用
pre<script>
脚本而不是在一行中包含多个步骤;和
- 重新使用
build
脚本,这样您就不必在两个地方进行更改。
你的情况:
"scripts": {
"build": "babel src/ --out-dir lib",
"pretest": "npm run build",
"test": "jest lib/*.test.js"
}
过去,如果不使用 Babel 转译代码,就无法在 Node 中使用 ES 模块(即 import
/export
)。然而,Node 中对 ES 模块的支持现在已经成为现实,Jest 和 Mocha 最近也都添加了对原生使用 ES 模块的支持。
然而,这不仅仅是将 "type": "module"
添加到您的 package.json。
在 Jest 中使用原生 ES 模块的步骤
如前所述,将 "type": "module"
添加到您的 package.json
将 jest-environment-node
或 jest-environment-jsdom-sixteen
安装到您的开发依赖项中。例如:
$ npm i -D jest-environment-node
更新 package.json 中的 Jest 配置并添加 testEnvironment
设置。例如:
"jest": {
"testEnvironment": "jest-environment-jsdom-node"
}
如果您使用的是 13.2 之前的 Node 版本,那么在 运行ning Node 时需要添加两个额外的标志:--experimental-modules
和 experimental-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
我添加了 type: module
但这没有帮助。
我正在尝试 运行 使用 import
和 export
作为源文件的 mocha 或 jest 测试。
关于此的现有问题具有与我的不同的细节,我也发现对于具有我特定情况的人来说,这些问题令人困惑,特别是因为我已经制定了一个具体的答案,其中的细节与现有问题无关,但是与我处境中的其他人相关。
您需要使用编译器,然后在运行测试时使用编译后的文件。
很多参考文献都说要加type: module
,但不多说了。
明确一点,基本信息:
SyntaxError: Cannot use import statement outside a module
是因为您正在使用 import
/export
并且 您正在尝试直接 运行 文件而无需编译。
这里的思维转变是习惯于在一个目录中编辑文件,运行在另一个目录中进行测试。或者,一些解决方案提供 "in'flight" 编译,因此这个细节基本上是隐藏的,只使用源文件。
根据具体需要,有几种不同的方法可以做到这一点。这是迄今为止我发现的最简单的方法之一,使用 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/
根据 the Jest documentation, if you make sure babel-jest
is installed and supply your Babel configuration per the Babel documentation,在配置文件中或 package.json
例如:
.babelrc.json
{
"presets": [
"@babel/env"
]
}
然后 babel-jest
将自动获取它,您无需显式预构建文件来测试它们。这也意味着您不必在调用 Babel 时在命令行上设置标志。
请注意,如果您确实想要明确预构建,我建议:
- 使用
pre<script>
脚本而不是在一行中包含多个步骤;和 - 重新使用
build
脚本,这样您就不必在两个地方进行更改。
你的情况:
"scripts": {
"build": "babel src/ --out-dir lib",
"pretest": "npm run build",
"test": "jest lib/*.test.js"
}
过去,如果不使用 Babel 转译代码,就无法在 Node 中使用 ES 模块(即 import
/export
)。然而,Node 中对 ES 模块的支持现在已经成为现实,Jest 和 Mocha 最近也都添加了对原生使用 ES 模块的支持。
然而,这不仅仅是将 "type": "module"
添加到您的 package.json。
在 Jest 中使用原生 ES 模块的步骤
如前所述,将
"type": "module"
添加到您的 package.json将
jest-environment-node
或jest-environment-jsdom-sixteen
安装到您的开发依赖项中。例如:$ npm i -D jest-environment-node
更新 package.json 中的 Jest 配置并添加
testEnvironment
设置。例如:"jest": { "testEnvironment": "jest-environment-jsdom-node" }
如果您使用的是 13.2 之前的 Node 版本,那么在 运行ning Node 时需要添加两个额外的标志:
--experimental-modules
和experimental-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