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

在Jest中导入ECMAScript包:动态import无法正常工作

问题:E2E测试中动态加载ESM包报错,运行时正常

现象

运行npm run start时功能正常,但端到端测试中加载ECMAScript包时触发错误:

TypeError: A dynamic import callback was not specified.

11 |   useFactory: async () => {
12 |     try {
>13 |       const pRetryPkg = await import(P_RETRY_PACKAGE_NAME);

错误代码:ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING

相关代码

import { Provider } from '@nestjs/common';

export const P_RETRY_PACKAGE_NAME = 'p-retry';

export interface PRetryEsmPackage {
  <T>(input: (attemptCount: number) => PromiseLike<T> | T, options?: Record<string, unknown>): Promise<T>;
}

export const PRetryPackageProvider: Provider = {
  provide: P_RETRY_PACKAGE_NAME,
  useFactory: async () => {
    try {
      const pRetryPkg = await import(P_RETRY_PACKAGE_NAME);
      return pRetryPkg.default as PRetryEsmPackage;
    } catch (error) {
      console.error(`Failed to load ${P_RETRY_PACKAGE_NAME}: ${error.message}`);
      throw error; // Re-throwing to ensure the provider fails if it's essential
    }
  },
};

已完成的配置

  1. 已设置环境变量NODE_OPTIONS=--experimental-vm-modules
  2. tsconfig核心配置:
{
  "compilerOptions": {
    ...
    "target": "ES2017",
    "module": "NodeNext",
    "emitDecoratorMetadata": true,
    "allowSyntheticDefaultImports": true,
    "incremental": true,
    "skipLibCheck": true,
    "moduleResolution": "NodeNext"
  }
}

调试建议

  • 确认Jest的ESM模式完全启用:
    检查jest.config.js(或jest.config.ts)中是否设置type: 'module',同时确保测试文件使用.mts/.mjs扩展名,或在项目根目录的package.json中添加"type": "module"。混用CommonJS与ESM模块可能导致动态import回调缺失。
  • 替换动态import的变量为字面量:
    临时将await import(P_RETRY_PACKAGE_NAME)改为await import('p-retry')测试。Jest在VM模块模式下处理动态变量的ESM导入时,可能存在兼容性问题。
  • 验证环境变量是否生效:
    在测试脚本中添加console.log(process.env.NODE_OPTIONS),确认--experimental-vm-modules已被正确传入。跨平台环境下可使用cross-env确保变量传递正常。
  • 禁用Jest缓存:
    运行测试时添加--no-cache参数,避免旧编译缓存引发的模块加载异常。
  • 检查p-retry包的导出格式:
    查看p-retry包的package.json,确认type字段是否为module,或是否同时提供ESM与CommonJS版本。若包为纯ESM,需确保Jest正确识别其模块类型。
  • 临时替换为静态导入测试:
    将动态import改为静态导入import pRetry from 'p-retry',若测试正常运行,说明问题出在动态import的VM模块处理上。可考虑在测试环境中提供Mock Provider替代动态加载逻辑。

内容的提问来源于stack exchange,提问作者klettg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 15:18:55