ts-jest项目中的ESM模块支持指南

ts-jest项目中的ESM模块支持指南

ts-jest A Jest transformer with source map support that lets you use Jest to test projects written in TypeScript. ts-jest 项目地址: https://gitcode.com/gh_mirrors/ts/ts-jest

前言

在现代JavaScript生态系统中,ES模块(ESM)已经成为标准模块系统。本文将详细介绍如何在ts-jest项目中配置和使用ESM支持,帮助开发者顺利过渡到ESM模块系统。

ESM支持的核心概念

基本要求

在使用ts-jest时,Jest会考虑以下ESM相关因素:

  1. ESM运行时环境
  2. tsconfig文件中module选项的值必须满足以下条件之一:
    • 设置为Node16/Node18/NodeNext,同时package.json中必须有"type": "module"
    • 或者设置为ES标准值,如ES2015ES2020

配置Jest运行时

注意事项

目前Jest运行时在ESM支持方面存在一些限制:

  1. 尚未完全支持根据package.json中的"type": "module"自动切换到ESM模式
  2. 对ES模块的模拟(mocking)功能尚未完全支持

启用ESM模式

要启用ESM支持,需要使用--experimental-vm-modules标志运行Jest:

node --experimental-vm-modules node_modules/jest/bin/jest.js

对于Yarn用户,可以使用以下替代命令:

yarn node --experimental-vm-modules $(yarn bin jest)

TypeScript配置提示

如果使用TypeScript编写Jest配置,需要安装ts-node作为开发依赖:

npm install -D ts-node

配置TypeScript

方案一:使用ES模块值

推荐使用ES2022ESNext以获得完整的ESM特性支持:

{
  "compilerOptions": {
    "module": "ES2022",
    "target": "ESNext",
    "esModuleInterop": true
  }
}

方案二:使用混合模块值

目前代码转换器仅支持在isolatedModules: true时使用混合值:

{
  "compilerOptions": {
    "module": "Node16",
    "target": "ESNext",
    "esModuleInterop": true,
    "isolatedModules": true
  }
}

配置Jest

使用ESM预设

ts-jest提供了专门的ESM预设创建函数:

import type { Config } from 'jest'
import { createDefaultEsmPreset } from 'ts-jest'

const presetConfig = createDefaultEsmPreset({
  // 可选配置项
})

export default {
  ...presetConfig,
} satisfies Config

不使用预设的手动配置

import type { Config } from 'jest'
import { TS_EXT_TO_TREAT_AS_ESM, ESM_TS_TRANSFORM_PATTERN } from 'ts-jest'

export default {
  extensionsToTreatAsEsm: [...TS_EXT_TO_TREAT_AS_ESM],
  transform: {
    [ESM_TS_TRANSFORM_PATTERN]: [
      'ts-jest',
      {
        useESM: true,
        // 其他ts-jest选项
      },
    ],
  },
} satisfies Config

处理.mjs/.mts扩展名

要支持.mts扩展名,除了启用ESM模式外,还需要:

  1. package.json中包含"type": "module"
  2. 自定义Jest解析器处理.mjs扩展名

示例解析器实现:

import type { SyncResolver } from 'jest-resolve'

const mjsResolver: SyncResolver = (path, options) => {
  const mjsExtRegex = /\.mjs$/i
  const resolver = options.defaultResolver
  if (mjsExtRegex.test(path)) {
    try {
      return resolver(path.replace(mjsExtRegex, '.mts'), options)
    } catch {
      // 回退到默认解析器
    }
  }
  return resolver(path, options)
}

export default mjsResolver

然后在Jest配置中引用:

import type { Config } from 'jest'

const config: Config = {
  resolver: '<rootDir>/path/to/custom-resolver.ts',
  // 其他配置项
}

常见问题解决

  1. 模块加载问题:对于Angular库的ESM构建文件或node_modules外的ESM文件,可能需要使用moduleNameMapper或自定义解析器
  2. 扩展名处理:确保正确处理.mjs/.mts扩展名,特别是当它们位于不同位置时
  3. 类型检查:使用isolatedModules: true可以提高类型检查的可靠性

最佳实践建议

  1. 对于新项目,推荐使用ES2022ESNext模块系统
  2. 大型项目迁移时,考虑逐步过渡,可以同时维护CJS和ESM配置
  3. 密切关注Jest对ESM支持的更新,特别是模拟功能的改进
  4. 对于混合代码库,自定义解析器可以提供更好的灵活性

通过遵循上述指南,开发者可以在ts-jest项目中充分利用ESM的优势,同时保持与现有测试基础设施的兼容性。

ts-jest A Jest transformer with source map support that lets you use Jest to test projects written in TypeScript. ts-jest 项目地址: https://gitcode.com/gh_mirrors/ts/ts-jest

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宗鲁宽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值