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

TypeScript项目Jest与TS编译模块导入冲突问题求助

解决Jest与NodeNext模块解析策略的导入冲突问题

问题背景

采用NodeNext模块解析策略的TypeScript项目中,测试文件src/tests/main.test.ts的导入语句出现矛盾:

  • 导入../main.js时,TypeScript编译器符合ES模块规范要求,但Jest报错无法找到该模块
  • 改为导入../main时,Jest能正常解析,但TypeScript编译器因违反ES模块必须带完整后缀的规则报错

项目配置

项目目录

.
├── jest.config.js
├── package.json
├── src
│   ├── main.ts
│   └── tests
│       └── main.test.ts
└── tsconfig.json

原始配置文件

jest.config.js

/** @type {import('ts-jest').JestConfigWithTsJest} */
export default {
  preset: 'ts-jest',
  testEnvironment: 'node',
};

package.json

{
  "type": "module",
  "scripts": {
    "test": "jest"
  },
  "devDependencies": {
    "@types/jest": "^29.2.4",
    "jest": "^29.3.1",
    "ts-jest": "^29.0.3"
  },
  "dependencies": {
    "chalk": "^5.1.2"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "rootDir": "./src",
    "outDir": "./dist",
    "strict": true,
    "skipLibCheck": true
  }
}

src/main.ts

import chalk from "chalk";

function dumyFn(num: number, num2: number) {
  return num + num2;
}

export { dumyFn };

原始测试文件及报错

src/tests/main.test.ts:

import { dumyFn } from "../main.js";
test("simple dummy test", () => {
  expect(dumyFn(2, 3)).toBe(5);
});

Jest报错:

FAIL src/tests/main.test.ts
  ● Test suite failed to run

    Cannot find module '../main.js' from 'tests/main.test.ts'

    > 1 | import { dumyFn } from "../main.js";
        | ^
      2 | test("simple dummy test", () => {
      3 |   expect(dumyFn(2, 3)).toBe(5);
      4 | });

      at Resolver._throwModNotFoundError (../node_modules/jest-resolve/build/resolver.js:425:11)
      at Object.<anonymous> (tests/main.test.ts:1:1)

改为import { dumyFn } from "../main";后,TypeScript编译器报错,提示缺少文件后缀。

解决方案

1. 调整Jest配置,适配ES模块与TS文件映射

修改jest.config.js,添加ESM支持及模块后缀映射,让Jest能识别导入语句中的.js后缀并映射到对应的.ts源码文件:

/** @type {import('ts-jest').JestConfigWithTsJest} */
export default {
  preset: 'ts-jest',
  testEnvironment: 'node',
  // 告知Jest将.ts文件视为ES模块
  extensionsToTreatAsEsm: ['.ts'],
  // 映射导入语句中的.js后缀到无后缀的文件(对应TS源码)
  moduleNameMapper: {
    '^(\\.{1,2}/.*)\\.js$': '$1',
  },
  // 启用ts-jest的ESM转换模式
  transform: {
    '^.+\\.tsx?$': ['ts-jest', { useESM: true }],
  },
};

2. 确保TypeScript编译器包含测试文件

修改tsconfig.json,添加include字段,让TypeScript能检查测试文件的导入规范:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "rootDir": "./src",
    "outDir": "./dist",
    "strict": true,
    "skipLibCheck": true
  },
  "include": ["src/**/*"]
}

3. 保留测试文件的.js后缀导入

测试文件src/tests/main.test.ts保持原导入语句不变:

import { dumyFn } from "../main.js";
test("simple dummy test", () => {
  expect(dumyFn(2, 3)).toBe(5);
});

验证

  1. 运行TypeScript编译:tsc,编译器不再报错
  2. 运行测试:npm run test,Jest能正常找到模块并执行测试

内容的提问来源于stack exchange,提问作者Iman Hosseinipour

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 04:20:21