You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 04:45:03