TypeScript项目中带.js扩展名的路径别名Jest适配问题
TypeScript项目中Jest与构建流程的模块扩展名冲突解决方案
问题背景
在TypeScript项目中使用Jest时遇到核心矛盾:
- 当import语句包含
.js扩展名时,Jest测试报错无法找到模块 - 移除
.js扩展名后,Jest测试正常,但项目构建流程会因缺少扩展名而报错无法定位模块
现有配置
Jest配置(jest.config.cjs)
const tsconfig = require('./tsconfig.json'); const moduleNameMapper = require('tsconfig-paths-jest')(tsconfig); module.exports = { preset: 'ts-jest', rootDir: './', modulePaths: ['<rootDir>'], testEnvironment: 'node', moduleFileExtensions: ['ts', 'js'], moduleNameMapper, moduleDirectories: ['src', 'test', 'node_modules'], };
TypeScript配置(tsconfig.json)
{ "compilerOptions": { "baseUrl": "./", "paths": { "~sourceService/*": ["src/services/source/*"], "~crawlService/*": ["src/services/crawl/*"], "~searchService/*": ["src/services/search/*"], "~test/*": ["test/*"], "~/*": ["src/*"] }, "rootDir": "./" } }
错误信息
test/unit/sourceService/sourceServiceFunctions.test.ts ● Test suite failed to run Configuration error: Could not locate module ~/config.js mapped as: C:\Users\USER\dir\project\src\$1. Please check your configuration for these entries: { "moduleNameMapper": { "/~\/(.*)/": " C:\Users\USER\dir\project\src\$1" }, "resolver": undefined } at createNoMappedModuleFoundError (node_modules/jest-resolve/build/resolver.js:759:17) at Object.require (src/services/source/source.utils.ts:4:1) at Object.<anonymous> (test/unit/sourceService/sourceServiceFunctions.test.ts:8:1)
已尝试方案
- Mock
~/config.js模块 - 在测试目录创建
__mocks__/config.ts - 修改jest.config.cjs添加规则移除相对路径的
.js扩展名并转为相对路径(非理想方案)
最优解决方案
核心思路是扩展Jest的moduleNameMapper规则,让它能正确解析带.js扩展名的路径别名,同时兼容TypeScript构建流程的要求。
修改jest.config.cjs,在原有moduleNameMapper基础上添加针对.js扩展名的映射规则:
const tsconfig = require('./tsconfig.json'); const moduleNameMapper = require('tsconfig-paths-jest')(tsconfig); module.exports = { preset: 'ts-jest', rootDir: './', modulePaths: ['<rootDir>'], testEnvironment: 'node', moduleFileExtensions: ['ts', 'js'], moduleNameMapper: { // 保留原有从tsconfig导入的映射规则 ...moduleNameMapper, // 添加针对带.js扩展名的别名映射 '^~/(.+)\\.js$': '<rootDir>/src/$1', '^~sourceService/(.+)\\.js$': '<rootDir>/src/services/source/$1', '^~crawlService/(.+)\\.js$': '<rootDir>/src/services/crawl/$1', '^~searchService/(.+)\\.js$': '<rootDir>/src/services/search/$1', '^~test/(.+)\\.js$': '<rootDir>/test/$1' }, moduleDirectories: ['src', 'test', 'node_modules'], };
方案说明
- 保留原有
tsconfig-paths-jest生成的映射规则,确保不带扩展名的别名正常工作 - 添加的新规则会匹配所有带
.js扩展名的别名路径,将其映射到对应的TypeScript文件路径(自动去除.js扩展名) - Jest的
moduleFileExtensions配置包含ts,所以会自动查找对应的.ts文件
额外优化建议
如果你的TypeScript配置使用了"module": "NodeNext"或"ESNext"(这类模块系统要求导入带扩展名),可以进一步调整Jest的transform配置,确保ts-jest能正确处理ES模块语法:
module.exports = { // ...其他配置 transform: { '^.+\\.tsx?$': ['ts-jest', { useESM: true }] }, };
同时在tsconfig.json中确保:
{ "compilerOptions": { // ...其他配置 "module": "NodeNext", "moduleResolution": "NodeNext", "esModuleInterop": true } }
这样配置后,既能满足构建流程对.js扩展名的要求,也能让Jest正确解析带扩展名的路径别名,测试和构建均可正常运行。
内容的提问来源于stack exchange,提问作者Wojciech Król
相关产品推荐
相关产品推荐

