TypeScript项目Jest与TS编译模块导入冲突问题求助
解决Jest与NodeNext模块解析策略的导入冲突问题
问题背景
采用NodeNext模块解析策略的TypeScript项目中,测试文件src/tests/main.test.ts的导入语句出现矛盾:
- 导入
../main.js时,TypeScript编译器符合ES模块规范要求,但Jest报错无法找到该模块 - 改为导入
../main时,Jest能正常解析,但TypeScript编译器因违反ES模块必须带完整后缀的规则报错
项目配置
项目目录
. ├── jest.config.js ├── package.json ├── src │ ├── main.ts │ └── tests │ └── main.test.ts └── tsconfig.json
原始配置文件
jest.config.js
/** @type {import('ts-jest').JestConfigWithTsJest} */ export default { preset: 'ts-jest', testEnvironment: 'node', };
package.json
{ "type": "module", "scripts": { "test": "jest" }, "devDependencies": { "@types/jest": "^29.2.4", "jest": "^29.3.1", "ts-jest": "^29.0.3" }, "dependencies": { "chalk": "^5.1.2" } }
tsconfig.json
{ "compilerOptions": { "target": "ES2022", "module": "NodeNext", "moduleResolution": "NodeNext", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "rootDir": "./src", "outDir": "./dist", "strict": true, "skipLibCheck": true } }
src/main.ts
import chalk from "chalk"; function dumyFn(num: number, num2: number) { return num + num2; } export { dumyFn };
原始测试文件及报错
src/tests/main.test.ts:
import { dumyFn } from "../main.js"; test("simple dummy test", () => { expect(dumyFn(2, 3)).toBe(5); });
Jest报错:
FAIL src/tests/main.test.ts ● Test suite failed to run Cannot find module '../main.js' from 'tests/main.test.ts' > 1 | import { dumyFn } from "../main.js"; | ^ 2 | test("simple dummy test", () => { 3 | expect(dumyFn(2, 3)).toBe(5); 4 | }); at Resolver._throwModNotFoundError (../node_modules/jest-resolve/build/resolver.js:425:11) at Object.<anonymous> (tests/main.test.ts:1:1)
改为import { dumyFn } from "../main";后,TypeScript编译器报错,提示缺少文件后缀。
解决方案
1. 调整Jest配置,适配ES模块与TS文件映射
修改jest.config.js,添加ESM支持及模块后缀映射,让Jest能识别导入语句中的.js后缀并映射到对应的.ts源码文件:
/** @type {import('ts-jest').JestConfigWithTsJest} */ export default { preset: 'ts-jest', testEnvironment: 'node', // 告知Jest将.ts文件视为ES模块 extensionsToTreatAsEsm: ['.ts'], // 映射导入语句中的.js后缀到无后缀的文件(对应TS源码) moduleNameMapper: { '^(\\.{1,2}/.*)\\.js$': '$1', }, // 启用ts-jest的ESM转换模式 transform: { '^.+\\.tsx?$': ['ts-jest', { useESM: true }], }, };
2. 确保TypeScript编译器包含测试文件
修改tsconfig.json,添加include字段,让TypeScript能检查测试文件的导入规范:
{ "compilerOptions": { "target": "ES2022", "module": "NodeNext", "moduleResolution": "NodeNext", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "rootDir": "./src", "outDir": "./dist", "strict": true, "skipLibCheck": true }, "include": ["src/**/*"] }
3. 保留测试文件的.js后缀导入
测试文件src/tests/main.test.ts保持原导入语句不变:
import { dumyFn } from "../main.js"; test("simple dummy test", () => { expect(dumyFn(2, 3)).toBe(5); });
验证
- 运行TypeScript编译:
tsc,编译器不再报错 - 运行测试:
npm run test,Jest能正常找到模块并执行测试
内容的提问来源于stack exchange,提问作者Iman Hosseinipour
相关产品推荐
相关产品推荐

