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

如何在Turborepo中配置ts-jest以兼容packages与apps目录测试?

Turborepo环境下ts-jest无法解析应用目录JSX测试文件的解决方案

问题场景

在Turborepo单体仓库中,/packages/ui下的组件测试能通过ts-jest正常运行,但/apps/my-app下的相同测试报错,核心错误为JSX语法无法解析:

FAIL my-app src/components/MyButton.test.tsx
 ● Test suite failed to run
   Jest encountered an unexpected token
   ...
   Details:
   /Users/me/repos/monorepo-root/apps/my-app/src/components/MyButton.test.tsx:14
        (0, test_utils_1.render)(<MyButton_1.MyButton onClick={onClick}/>);
                                 ^
    SyntaxError: Unexpected token '<'

当前公共jest配置(/packages/jest-config/jest-preset.js):

module.exports = {
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
  modulePathIgnorePatterns: [
    '<rootDir>/test/__fixtures__',
    '<rootDir>/node_modules',
    '<rootDir>/dist',
  ],
  projects: [{
    displayName: 'ui',
    preset: 'ts-jest',
    testEnvironment: 'jest-environment-jsdom',
    testMatch: ['<rootDir>/../ui/**/*.@(spec|test).ts?(x)'],
  },
  {
    displayName: 'my-app',
    preset: 'ts-jest',
    testEnvironment: 'jest-environment-jsdom',
    testMatch: ['<rootDir>/../../apps/my-app/**/*.@(spec|test).ts?(x)'],
  }],
  transform: {
    '^.+\\.tsx?$': 'ts-jest',
  },
};

仓库目录结构:

monorepo-root
├─ packages
│  ├─ ui/
│  │  └─ MyButton.test.tsx # 测试通过
│  └─ jest-config/
│     └─ jest-preset.js
└─ apps/
   └─ my-app/
      └─ MyButton.test.tsx # 测试失败

核心原因

  1. <rootDir>路径解析混乱:多项目配置中,每个子项目的<rootDir>默认指向自身根目录,但当前testMatch使用跨目录相对路径,导致全局transform规则未正确匹配到应用目录的文件。
  2. 子项目未继承/触发transform规则:全局配置的transform未被每个子项目正确继承,应用目录的tsx文件未经过ts-jest转译就被Jest执行,导致JSX语法报错。

解决方法

方法1:为每个子项目明确配置根目录与transform

修改公共jest配置文件,给每个项目单独指定rootDir和transform,确保路径匹配与转译规则生效:

module.exports = {
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
  modulePathIgnorePatterns: [
    '<rootDir>/test/__fixtures__',
    '<rootDir>/node_modules',
    '<rootDir>/dist',
  ],
  projects: [{
    displayName: 'ui',
    rootDir: '<rootDir>/../ui', // 明确指定ui包根目录
    preset: 'ts-jest',
    testEnvironment: 'jest-environment-jsdom',
    testMatch: ['**/*.@(spec|test).ts?(x)'],
    transform: {
      '^.+\\.tsx?$': 'ts-jest',
    },
  },
  {
    displayName: 'my-app',
    rootDir: '<rootDir>/../../apps/my-app', // 明确指定应用根目录
    preset: 'ts-jest',
    testEnvironment: 'jest-environment-jsdom',
    testMatch: ['**/*.@(spec|test).ts?(x)'],
    transform: {
      '^.+\\.tsx?$': 'ts-jest',
    },
  }],
};

方法2:分项目配置jest文件

在apps/my-app目录下创建独立的jest.config.js,继承公共配置:

// apps/my-app/jest.config.js
module.exports = {
  preset: '../../packages/jest-config/jest-preset.js',
  rootDir: '.',
  testMatch: ['**/*.@(spec|test).ts?(x)'],
};

同时修改公共配置为基础预设(移除多项目配置):

// packages/jest-config/jest-preset.js
module.exports = {
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
  modulePathIgnorePatterns: [
    '<rootDir>/test/__fixtures__',
    '<rootDir>/node_modules',
    '<rootDir>/dist',
  ],
  preset: 'ts-jest',
  testEnvironment: 'jest-environment-jsdom',
  transform: {
    '^.+\\.tsx?$': 'ts-jest',
  },
};

最后在仓库根目录创建jest.config.js统一管理多项目:

// monorepo-root/jest.config.js
module.exports = {
  projects: [
    '<rootDir>/packages/ui/jest.config.js',
    '<rootDir>/apps/my-app/jest.config.js',
  ],
};

方法3:排查依赖转译问题(可选)

如果应用依赖了未预编译的第三方包,需要在配置中添加transformIgnorePatterns,允许ts-jest转译这些包:

// 在对应项目的jest配置中添加
transformIgnorePatterns: [
  'node_modules/(?!(your-uncompiled-package-name)/)',
],

验证

修改配置后,运行以下命令测试应用目录的测试是否正常:

npx jest --projects apps/my-app

内容的提问来源于stack exchange,提问作者Ben Wong

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 00:01:15