You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置ts-jest实现CommonJS动态导入ESM模块的测试?

问题场景

现有一个基于CommonJS模块系统的库,通过以下动态导入函数加载仅支持ESM的模块(目的是避免TypeScript将import语法替换为require):

export async function loadEsmModule<T>(modulePath: string|URL): Promise<T> {
    const namespaceObject =
        (await new Function('modulePath', `return import(modulePath);`)(modulePath));

    // 若目标模块不是ESM,所需值会存储在`default`属性中
    if (namespaceObject.default) {
        return namespaceObject.default;
    } else {
        return namespaceObject;
    }
}

使用ts-jest运行该库的CommonJS单元测试时,尝试多种配置组合均失败:

  • 启用Node.js实验性选项--experimental-vm-modules:触发worker进程崩溃,报错"A jest worker process (pid=2701) was terminated by another process: signal=SIGSEGV, exitCode=null. Operating system logs may contain more information on why this occurred."
  • 使用Jest选项--runInBand:报错"Test environment has been torn down"
  • 调大maxWorkers和maxConcurrency参数:无任何改善
  • 切换不同ts-jest预设:问题依旧
可行配置方案

针对该混合模块场景,以下配置组合可解决测试运行问题:

1. Jest配置文件(jest.config.js)

采用CommonJS格式配置,明确指定CommonJS模块模式,适配ts-jest的转换规则:

module.exports = {
  preset: 'ts-jest/presets/js-with-ts',
  testEnvironment: 'node',
  moduleFileExtensions: ['ts', 'js', 'json'],
  transform: {
    '^.+\\.tsx?$': ['ts-jest', {
      useESM: false, // 强制ts-jest以CommonJS模式编译TypeScript代码
      isolatedModules: true
    }]
  },
  // 禁用Jest自动识别ESM的逻辑,避免模块类型混淆
  extensionsToTreatAsEsm: [],
  // 强制Jest使用CommonJS模块系统处理所有文件
  moduleType: 'commonjs',
  // 可选:针对特定ESM依赖添加路径映射(若依赖导入路径存在问题)
  moduleNameMapper: {
    // 示例:映射ESM依赖的入口文件
    // '^some-esm-lib$': '<rootDir>/node_modules/some-esm-lib/index.js'
  }
};

2. 测试运行命令

在package.json的scripts中配置测试命令,不要启用--experimental-vm-modules(该实验性特性在混合模块场景下稳定性极差):

{
  "scripts": {
    "test": "jest --verbose"
  }
}

3. 关键配置说明

  • preset: 'ts-jest/presets/js-with-ts':该预设专为CommonJS项目设计,会将TypeScript代码编译为CommonJS格式,同时兼容JavaScript文件。
  • useESM: false:禁止ts-jest启用ESM转换模式,确保编译后的测试代码和库代码均为CommonJS,避免与动态导入的ESM模块产生模块系统冲突。
  • extensionsToTreatAsEsm: []:关闭Jest自动将.js或.ts文件识别为ESM的逻辑,防止Jest误判模块类型引发错误。
  • 放弃--experimental-vm-modules:该选项是导致worker进程崩溃的核心原因,Jest在处理混合模块时对该实验性特性的支持尚未成熟,完全禁用即可避免崩溃问题。

4. 测试文件编写规范

测试文件保持CommonJS风格(或让ts-jest自动转换为CommonJS),避免在测试代码中直接使用ESM语法:

// 测试文件示例
const { loadEsmModule } = require('../src/your-library');

test('成功加载ESM模块', async () => {
  const esmModule = await loadEsmModule('target-esm-module');
  expect(esmModule).toBeDefined();
});

内容的提问来源于stack exchange,提问作者daniel-sc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 09:10:13