Jest@28升级后babel-jest无法自动识别Babel配置的问题咨询
问题背景
在基于Lerna + Yarn Classic Workspaces的Monorepo里,把Jest从27升到28后,发现babel-jest不再自动识别仓库根目录的babel.config.js,必须在Jest通用配置里手动指定configFile才能正常转译TypeScript测试代码。
项目核心信息:
- Jest和Babel相关依赖均作为Workspace依赖安装
- 仓库根目录有
babel.config.js,专门配置Jest转译TS测试的规则 - Jest根配置
root.config.js放在<wkspceRoot>/scripts/jest,设置了rootDir: '../..'并指定所有子项目 - 所有子项目共用的
common.config.js也位于<wkspceRoot>/scripts/jest目录下
对Jest 28破坏性变更的解释
迁移指南里提到的这段描述:
babel-jest现在在解析配置时会将root: config.rootDir传递给Babel。这提升了不同配置项目的兼容性,但可能导致你的Babel配置无法按原有方式被识别。
直白拆解:
- Jest 27及更早版本,
babel-jest是从当前测试文件所在目录向上递归查找Babel配置文件(比如babel.config.js或.babelrc) - 到了Jest 28,
babel-jest会强制把Jest配置中的rootDir作为Babel解析配置时的根路径。但你的Jest配置文件放在scripts/jest目录,加上子项目的执行上下文,导致路径解析逻辑和之前不一致,根目录的babel.config.js就没被自动找到。
无需手动指定configFile的解决方案
方案1:统一Jest的rootDir与Babel配置路径
你的babel.config.js在仓库根目录,而Jest根配置已经把rootDir设为仓库根(../..),可以在Jest根配置里统一设置transform,让所有子项目继承,不用在common配置里手动指定:
// root.config.js module.exports = { rootDir: '../..', projects: [ '<rootDir>/packages/@scope/packageA', '<rootDir>/packages/@scope/packageB', '<rootDir>/packages/@scope/packageC', ], coverageThreshold: { global: { branches: 80, functions: 85, lines: 85, }, }, // 统一配置transform,让babel-jest自动查找根目录的配置 transform: { '^.+\\.[jt]sx?$': 'babel-jest', }, };
同时保持common.config.js的简洁配置:
// common.config.js module.exports = { testMatch: ['<rootDir>/**/__tests__/**/*.spec.ts'], };
方案2:给Babel配置添加rootMode
babel.config.js本身是项目级配置,默认应该被所有子项目识别,加上rootMode: 'upward'可以强制Babel从当前目录向上递归查找配置,直到找到仓库根的babel.config.js,不受babel-jest传递的root参数影响:
// babel.config.js module.exports = { rootMode: 'upward', presets: [ ['@babel/preset-env', { targets: { node: 'current' } }], '@babel/preset-typescript' ] }
方案3:确保子项目Jest配置的路径解析正确
子项目导入common.config.js时,要明确相对路径,避免<rootDir>解析混乱:
// packages/@scope/packageA/jest.config.js module.exports = { ...require('../../scripts/jest/common.config.js'), // 子项目专属配置 };
总结
Jest 28的这个变更核心就是修改了babel-jest传递给Babel的根路径,从测试文件目录变成了Jest的rootDir,打乱了之前的自动查找逻辑。通过统一Jest配置的rootDir、给Babel加rootMode,或者在Jest根配置里统一设置transform,都能让babel-jest自动识别根目录的Babel配置,不用手动指定configFile。
内容的提问来源于stack exchange,提问作者Monad

