如何解决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
相关产品推荐
相关产品推荐

