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

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'],
};

方案说明

  1. 保留原有tsconfig-paths-jest生成的映射规则,确保不带扩展名的别名正常工作
  2. 添加的新规则会匹配所有带.js扩展名的别名路径,将其映射到对应的TypeScript文件路径(自动去除.js扩展名)
  3. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 08:05:21