Jest 中使用 ESModules

Jest 中使用 ESModules.png

前言:目前 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,启用的话两种方式:

  1. package.json 增加 "type": "module", 字段。
  2. 文件的扩展名改为 .mjs

好了,了解完 NodeJS 对 ESM 支持,接下来我们就看看 Jest 结合 NodeJS 支持 JavaScript 版 ESM 如何配置。

  • 首先确认你的 NodeJS 版本大于等于 14.13.1
➜  jest_project node -v
v16.4.1
  • 接下来,你需要禁用 Jest 的 transform: {} 配置,你有两种方式可供选择,

    1. 第一种是在 package.json 文件中,添加:
  "jest": {
    "transform": {}
  },
  1. 第二种是在 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,有两种办法:

  1. 书写 .mjs 扩展名的文件。
  2. 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

你可能感兴趣的:(Jest 中使用 ESModules)