前言:目前 Jest 默认支持的模块语法是 CommonJS,但是毫无疑问我们项目基本都是基于 ESModules 来开发的,那么问题来了,我们如何在 Jest 中去支持 ESModules 呢。
目录
- Jest 结合 NodeJS 支持 JavaScript 版 ESM。
- Jest 结合 NodeJS 支持 TypeScript 版 ESM。
- Jest 结合 Babel,支持 JavaScript 版 ESM。
- Jest 结合 Babel,支持 TypeScript 版 ESM。
- Webpack 等工具支持 TypeScript/JavaScript 版 ESM。
- 总结
- 参考
Jest 结合 NodeJS 支持 JavaScript 版 ESM
NodeJS 14.13.1
之后的版本都支持了 ESM,启用的话两种方式:
-
package.json
增加"type": "module",
字段。 - 文件的扩展名改为
.mjs
。
好了,了解完 NodeJS 对 ESM 支持,接下来我们就看看 Jest 结合 NodeJS 支持 JavaScript 版 ESM 如何配置。
- 首先确认你的 NodeJS 版本大于等于
14.13.1
。
➜ jest_project node -v
v16.4.1
-
接下来,你需要禁用 Jest 的
transform: {}
配置,你有两种方式可供选择,- 第一种是在
package.json
文件中,添加:
- 第一种是在
"jest": {
"transform": {}
},
- 第二种是在 Jest 的配置文件通过 ESM 方式禁用
transform: {}
,例如:
// jest.config.js
export default {
transform: {}
}
- 然后,设置环境变量,通过执行 NodeJS 命令同时携带
--experimental-vm-modules
参数,例如在package.json
中:
"scripts": {
"test": "NODE_OPTIONS=--experimental-vm-modules jest --watchAll",
},
- 最后,支持 ESM 文件, ESM 文件我们可以通过
.mjs
扩展名来声明,也可以通过package.json
中 type 字段声明,使用 type 字段声明的好处是可以保留.js
后缀名,package.json
中的 type 字段:
"type": "module"
这时我们就可以使用 ESM 来编写测试文件了。
Jest 结合 NodeJS 支持 TypeScript 版 ESM。
随着 TypeScript 的大规模的使用,我们项目不可避免的需要用到 TypeScript 来编写测试,ESM 中应该如何支持 TypeScript 呢。
现在 Jest 项目中支持 ESM,有两种办法:
- 书写
.mjs
扩展名的文件。 -
package.json
支持 type 字段的.js
文件。
如果我们想要其他文件,原生支持 ESM,我们可以使用 Jest 的配置参数 extensionsToTreatAsEsm
option 来实现。
我们在 Jest 的配置文件,添加如下代码:
extensionsToTreatAsEsm: [".ts"]
然后把项目中的测试文件改成 .ts
结尾,重新 npm run test
运行测试用例即可。
Jest 结合 Babel,支持 JavaScript 版 ESM
Babel 的作用是把 ES6+ 语法转换成 ES5 语法,ESM 属于 ES6+ 的内容,被 Babel 转成 ES5 之后就是一个立即执行表达式(IIFE),这时 Jest 当然就不存在不支持 ESM 的问题了。
如果想让 Babel 支持 ESM,我们需要三个 npm package,首先需要@babel/core
然后支持 ES 语法转换的 @babel/preset-env
,最后和 Jest 通信的 babel-jest
。
但是因为我们在安装 Jest 的时候 babel-jest
默认被安装了,所以我们只需要安装,剩下两个 package 就行了。
安装依赖:
npm install @babel/core @babel/preset-env
package.json
同级目录下新建 babel.config.js
文件,内容输入为:
// babel.config.js
module.exports = {
presets: [["@babel/preset-env", { targets: { node: "current" } }]],
// node: "current" 表示基于你当前 Node 的版本进行编译,其中 current 可替换为 process.versions.node
};
重新 npm run test
运行测试用例即可。
Jest 结合 Babel,支持 TypeScript 版 ESM
接下来如果我们想在 TypeScript 中使用 ESM,我们需要一个新的 package 来吧 TS 转译成 JS,这个 package 就是 @babel/preset-typescript
:
添加新的 package @babel/preset-typescript
:
npm install --save-dev @babel/preset-typescript
然后在 Babel 的 presets 配置中新增 @babel/preset-typescript
:
module.exports = {
presets: [
["@babel/preset-env", { targets: { node: "current" } }],
"@babel/preset-typescript"
],
};
然后把项目中的测试文件改成 .ts
结尾,重新 npm run test
运行测试用例即可。
Webpack 等工具支持 TypeScript/JavaScript 版 ESM
原理类似 Babel ,具体演示自己探索吧,就不演示了。
总结
今天,我们主要学习了在 Jest 中去支持 ESModules,实现的方法有很多,但是我主要演示了:
- Jest 借用 NodeJS 支持 ESModules。
- Jest 借用 Babel 支持 ESModules。
参考
- https://jestjs.io/docs/ecmascript-modules
- getting-started-Using Babel
- @babel/preset-env