NestJS项目运行Jest时无法解析别名路径问题求助
解决Jest无法识别TypeScript路径别名的问题
问题现象
项目执行npm run start:dev完全正常,但运行npm run test或npm run test:e2e时,Jest提示无法找到@user/user.service、@common/decorators等通过TypeScript路径别名映射的模块。
报错信息
FAIL src/teacher/teacher.service.spec.ts ● Test suite failed to run Configuration error: Could not locate module @user/user.service mapped as: D:\Diplom_backend\nestjs-project\src\user. Please check your configuration for these entries: { "moduleNameMapper": { "/@user/": "D:\\Diplom_backend\\nestjs-project\\src\\user" }, "resolver": undefined } 1 | import { Injectable } from '@nestjs/common'; 2 | import { PrismaService } from '@prisma/prisma.service'; > 3 | import { UserService } from '@user/user.service'; | ^ 4 | import { CreditService } from 'src/credit/credit.service'; 5 | import { LessonService } from 'src/lesson/lesson.service'; 6 | import { MarkService } from 'src/mark/mark.service'; at createNoMappedModuleFoundError (node_modules/jest-resolve/build/resolver.js:759:17) at Object.<anonymous> (src/teacher/teacher.service.ts:3:1) at Object.<anonymous> (src/teacher/teacher.service.spec.ts:2:1) FAIL src/teacher/teacher.controller.spec.ts ● Test suite failed to run Configuration error: Could not locate module @common/decorators mapped as: D:\Diplom_backend\nestjs-project\libs\common\src. Please check your configuration for these entries: { "moduleNameMapper": { "/@common/": "D:\\Diplom_backend\\nestjs-project\\libs\\common\\src" }, "resolver": undefined } 1 | import { JwtPayload } from '@auth/interfaces'; > 2 | import { CurrentUser, Public } from '@common/decorators'; | ^ 3 | import { Controller, Get, Param } from '@nestjs/common'; 4 | import { TeacherService } from './teacher.service'; 5 | import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'; at createNoMappedModuleFoundError (node_modules/jest-resolve/build/resolver.js:759:17) at Object.<anonymous> (src/teacher/teacher.controller.ts:2:1) at Object.<anonymous> (src/teacher/teacher.controller.spec.ts:2:1) Test Suites: 2 failed, 2 total
当前配置文件
package.json中的Jest配置
"jest": { "moduleFileExtensions": [ "js", "json", "ts" ], "rootDir": ".", "testRegex": ".*\\.spec\\.ts$", "transform": { "^.+\\.(t|j)s$": "ts-jest" }, "collectCoverageFrom": [ "**/*.(t|j)s" ], "coverageDirectory": "./coverage", "testEnvironment": "node", "roots": [ "<rootDir>/src/", "<rootDir>/libs/" ], "moduleNameMapper": { "@prisma": "<rootDir>/src/prisma", "@prisma/(.*)": "<rootDir>/src/prisma/$1", "@user": "<rootDir>/src/user", "@user/(.*)": "<rootDir>/src/user/$1", "@common": "<rootDir>/libs/common/src", "@common/(.*)": "<rootDir>/libs/common/src/$1", "@auth": "<rootDir>/src/auth", "@auth/(.*)": "<rootDir>/src/auth/$1" } }
tsconfig.json配置
"baseUrl": "./", "rootDir": "./", "paths": { "@prisma": ["src/prisma"], "@prisma/*": ["src/prisma/*"], "@user": ["src/user"], "@user/*": ["src/user/*"], "@common": ["libs/common/src"], "@common/*": ["libs/common/src/*"], "@auth": ["src/auth"], "@auth/*": ["src/auth/*"] }
jest-e2e.json配置
{ "moduleFileExtensions": ["js", "json", "ts"], "rootDir": ".", "testEnvironment": "node", "testRegex": ".e2e-spec.ts$", "transform": { "^.+\\.(t|j)s$": "ts-jest" }, "moduleNameMapper": { "@prisma": "<rootDir>/../src/prisma", "@prisma/(.*)": "<rootDir>/../src/prisma/$1", "@user": "<rootDir>/../src/user", "@user/(.*)": "<rootDir>/../src/user/$1", "@common": "<rootDir>/../libs/common/src", "@common/(.*)": "<rootDir>/../libs/common/src/$1", "@auth": "<rootDir>/../src/auth", "@auth/(.*)": "<rootDir>/../src/auth/$1" } }
解决方案
1. 修正Jest的moduleNameMapper为正则表达式格式
Jest对带后缀的别名(如@user/user.service)需要用正则表达式精确匹配并捕获子路径,否则会出现替换不完整的问题。修改package.json中的Jest配置:
"jest": { // ... 其他配置不变 "moduleNameMapper": { "^@prisma$": "<rootDir>/src/prisma", "^@prisma/(.*)$": "<rootDir>/src/prisma/$1", "^@user$": "<rootDir>/src/user", "^@user/(.*)$": "<rootDir>/src/user/$1", "^@common$": "<rootDir>/libs/common/src", "^@common/(.*)$": "<rootDir>/libs/common/src/$1", "^@auth$": "<rootDir>/src/auth", "^@auth/(.*)$": "<rootDir>/src/auth/$1" } }
2. 修正jest-e2e.json的moduleNameMapper
同样将e2e测试的映射改为正则格式,确保路径替换正确:
{ // ... 其他配置不变 "moduleNameMapper": { "^@prisma$": "<rootDir>/../src/prisma", "^@prisma/(.*)$": "<rootDir>/../src/prisma/$1", "^@user$": "<rootDir>/../src/user", "^@user/(.*)$": "<rootDir>/../src/user/$1", "^@common$": "<rootDir>/../libs/common/src", "^@common/(.*)$": "<rootDir>/../libs/common/src/$1", "^@auth$": "<rootDir>/../src/auth", "^@auth/(.*)$": "<rootDir>/../src/auth/$1" } }
3. 验证配置一致性
确保tsconfig.json的paths配置与Jest的映射完全对应,现有tsconfig.json配置正确,无需修改。
原因说明
Jest默认将moduleNameMapper中的字符串键视为前缀匹配,当别名后带有子路径(如@user/user.service)时,前缀匹配会仅替换@user部分,导致最终路径缺失子路径(变成src/user而非src/user/user.service)。使用正则表达式并通过$1捕获子路径,可以完整替换整个别名路径,解决模块找不到的问题。
内容的提问来源于stack exchange,提问作者user24119247
相关产品推荐
相关产品推荐

