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

如何解决Jest在NestJS/TypeScript/ESModules项目中运行报错问题

解决ESModules模式下NestJS+Jest的import语法错误

问题原因

你的项目通过package.json的"type": "module"配置为ESModules,但Jest默认以CommonJS模式运行,导致测试文件中的import语句被识别为非法语法,抛出SyntaxError: Cannot use import statement outside a module错误。

解决方案

1. 升级Jest配置支持ESModules

修改jest.config.ts,添加ESModule适配配置:

export default {
  preset: 'ts-jest',
  rootDir: '.',
  testEnvironment: 'node',
  // 标记.ts文件为ES模块
  extensionsToTreatAsEsm: ['.ts'],
  // 让ts-jest启用ESM编译模式
  globals: {
    'ts-jest': {
      useESM: true,
    },
  },
  // 自动映射.js后缀的导入到对应的.ts文件(解决测试时找不到编译后js文件的问题)
  moduleNameMapper: {
    '^(\\.{1,2}/.*)\\.js$': '$1',
  },
  projects: [
    {
      displayName: 'unit',
      testMatch: ['<rootDir>/src/**/*.spec.ts'],
    },
  ],
};

2. 给测试环境单独配置TypeScript(推荐)

创建tsconfig.test.json,和生产编译配置隔离,避免冲突:

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "allowImportingTsExtensions": true, // 测试环境允许直接导入.ts文件
    "noEmit": true
  }
}

然后在jest.config.ts的globals.ts-jest里指定这个配置:

globals: {
  'ts-jest': {
    useESM: true,
    tsconfig: './tsconfig.test.json',
  },
},

3. 调整测试文件导入(二选一)

  • 如果你用了moduleNameMapper,可以保持测试文件里的.js导入不变,Jest会自动映射到.ts源文件;
  • 如果你用了测试专用的TS配置,直接把导入改成.ts后缀:
    // 替换原来的.js导入
    import { HttpExceptionFilter } from './http-exception.filter.ts'
    

4. 确认package.json配置无误

保持type: module不变,测试命令正常:

{
  "name": "server",
  "type": "module",
  "scripts": {
    "test": "jest"
  }
}

关键细节解释

  • extensionsToTreatAsEsm:告诉Jest不要把.ts文件当作CommonJS处理,适配ESModule语法;
  • ts-jest.useESM:让ts-jest编译TS文件时输出ESModule格式,而非默认的CommonJS;
  • moduleNameMapper:解决测试阶段还未编译出.js文件时,导入.js找不到的问题;
  • 测试专用TS配置:既满足测试时直接导入.ts文件的需求,又不影响生产环境NestJS依赖dist目录的编译逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 00:33:07