ESM Node.js应用中使用Jest测试Express接口时模块导入失败
解决Express+TypeScript+Jest ESM导入冲突问题
问题根源
你当前的moduleNameMapper规则"(.+)\\.js": "$1"会无差别匹配所有带.js后缀的模块,包括node_modules里的第三方依赖(比如Express依赖的ipaddr.js)。Jest会尝试寻找去掉.js后缀的ipaddr模块,而这个模块并不存在,因此抛出找不到模块的错误。
解决方案
修改moduleNameMapper规则,只匹配项目自身的文件,排除第三方依赖。使用正则路径前缀限定,确保仅处理你自己写的相对路径模块。
调整后的Jest配置
"jest": { "setupFiles": [ "<rootDir>/src/test.setup.ts" ], "testRegex": "src/.*\\.test\\.(t|j)sx?$", "transform": { "\\.[jt]sx?$": "ts-jest" }, "globals": { "ts-jest": { "useESM": true } }, "moduleNameMapper": { "^(\\./.*)\\.js$": "$1" }, "extensionsToTreatAsEsm": [ ".ts" ], "moduleFileExtensions": ["ts", "js"] }
关键配置说明
moduleNameMapper的正则^(\\./.*)\\.js$:仅匹配以./开头的相对路径文件(即你项目内的模块),将.js后缀移除,既满足ESM导入要求,又不会干扰第三方依赖的解析。moduleFileExtensions:显式指定Jest需要处理的文件扩展名,确保TS和JS文件都能被正确识别。
额外优化建议
如果希望从根源上减少手动添加.js后缀的麻烦,可以将tsconfig.json中的moduleResolution改为node16或nodenext,这两个模式更贴合Node.js的ESM解析规则,允许TypeScript自动处理扩展名映射,无需手动在导入时添加.js。修改后的tsconfig关键配置:
{ "compilerOptions": { "module": "ES2020", "target": "ES2020", "esModuleInterop": true, "moduleResolution": "node16", // 改为node16或nodenext "sourceMap": true, "outDir": "./dist" }, "include": ["src"] }
内容的提问来源于stack exchange,提问作者Siepraa
相关产品推荐
相关产品推荐

