
Jest 默认不支持 import/export 等 ES 模块语法,会报“Cannot use import statement outside a module”错误;需通过 Babel 配置将其转译为 CommonJS,并合理设置 transformIgnorePatterns 以覆盖第三方 ESM 依赖。
jest 默认不支持 `import`/`export` 等 es 模块语法,会报“cannot use import statement outside a module”错误;需通过 babel 配置将其转译为 commonjs,并合理设置 `transformignorepatterns` 以覆盖第三方 esm 依赖。
Jest 在 v29+ 版本中仍默认以 CommonJS(CJS)模式运行,无法原生解析 import 语句——即使你的源码或依赖(如较新版本的 axios)已发布为 ESM 格式,Jest 也会在解析阶段直接抛出 SyntaxError。根本原因在于:Jest 的运行时未启用 ESM 支持,且 babel-jest 默认配置可能未强制输出 CJS。
✅ 推荐解决方案:配置 Babel 将 ESM 转为 CJS
在项目根目录创建 babel.config.js(不要用 .babelrc,因 Jest v27+ 推荐使用 JS 配置以支持条件逻辑):
// babel.config.js
module.exports = (api) => {
const isTest = api.env('test');
return {
presets: [
[
'@babel/preset-env',
{
targets: {
node: isTest ? 'current' : 'es2022', // 测试环境强制转为当前 Node 的 CJS
},
modules: isTest ? 'commonjs' : undefined, // 关键!测试时禁用 ES 模块输出
},
],
],
plugins: isTest
? ['@babel/plugin-transform-modules-commonjs'] // 显式确保 import → require
: [],
};
};
同时,更新 package.json 中的 Jest 配置,显式启用对 node_modules 中 ESM 包的转译(例如 axios@1.6+ 默认仅发布 ESM):
"jest": {
"transform": {
"^.+\.jsx?$": "babel-jest"
},
"transformIgnorePatterns": [
"/node_modules/(?!(axios|some-other-esm-lib)/)" // 仅忽略白名单外的模块
],
"testEnvironment": "jsdom"
}
⚠️ 注意事项:
- 不要启用 Jest 官方实验性 ESM 支持(
"type": "module"+"extensionsToTreatAsEsm": [".js"]),因其在 monorepo、worker 线程及部分 mock 场景下不稳定,官方明确标注为 not production ready; -
transformIgnorePatterns是关键突破口:Jest 默认跳过node_modules,但现代库(如axios,zod,valibot)越来越多采用纯 ESM 发布,必须显式放行; - 若使用 Create React App(CRA),其内置
react-scripts锁定了 Jest 和 Babel 版本,建议升级至react-scripts@5.0+并手动覆盖 Babel 配置,或考虑迁移到Vite + Vitest以获得开箱即用的 ESM 支持。
总结:解决 Jest ESM 识别问题的核心是「转译时机 + 转译目标 + 转译范围」三者协同——用 @babel/preset-env 在测试环境下强制生成 CJS,配合精准的 transformIgnorePatterns 打开必要依赖的转译通道,即可稳定运行基于现代 JavaScript 的测试套件。











