Jest 测试中解决 "Cannot use import statement outside a module" 错误
问题分析
当在 Jest 测试环境中使用 Axios 1.x+ 版本时,常会遇到 Cannot use import statement outside a module
错误。这是因为:
- Axios 1.0+ 将模块系统从 CommonJS 切换为 ECMAScript Modules (ESM)
- Jest 运行在 Node.js 环境,默认使用 CommonJS 模块系统
- Jest 默认忽略
node_modules
目录的代码转换
错误原因
Axios 1.x 的入口文件使用 ESM 语法:
js
import axios from './lib/axios.js'; // Axios 1.x 的入口文件语法
export default axios;
而 Jest 无法直接执行 ESM 语法,导致测试失败。
解决方案
方法一:配置 moduleNameMapper 指向 CommonJS 版本(推荐)
修改 Jest 配置,强制使用 Axios 的 CommonJS 版本:
js
module.exports = {
// 其他配置...
moduleNameMapper: {
'^axios$': 'axios/dist/node/axios.cjs'
}
};
json
{
"jest": {
"moduleNameMapper": {
"^axios$": "axios/dist/node/axios.cjs"
}
}
}
方法二:配置 transformIgnorePatterns 转换 Axios 模块
允许 Jest 转换 Axios 模块,忽略其他 node_modules
:
js
module.exports = {
transformIgnorePatterns: [
'node_modules/(?!axios)' // 排除 axios 的忽略规则
]
};
json
{
"jest": {
"transformIgnorePatterns": [
"node_modules/(?!axios)"
]
}
}
方法三:在测试脚本中直接指定配置
通过命令行传递 transformIgnorePatterns
参数:
json
{
"scripts": {
"test": "react-scripts test --transformIgnorePatterns \"node_modules/(?!axios)/\""
}
}
正则表达式解释
node_modules/(?!axios)
表示:"排除所有 node_modules 目录,但 axios 除外"
方法四:更新 Jest 和相关依赖
较旧的 Jest 版本可能不兼容新的模块系统,更新依赖:
bash
npm install --save-dev jest@29 ts-jest@29
特殊情况处理
使用 axios-mock-adapter 时的处理
当配合 axios-mock-adapter
使用时,推荐使用 transformIgnorePatterns
方案:
js
// jest.config.js
module.exports = {
transformIgnorePatterns: [
"/node_modules/(?!(axios)/)"
]
};
清除 Jest 缓存
如果配置修改未生效,尝试清除缓存:
bash
npm test -- --clearCache
不推荐的方案:直接修改导入路径
虽然可行,但不建议在项目代码中直接指定 Axios 构建路径:
js
// 不推荐 - 侵入代码实现细节
import axios from 'axios/dist/browser/axios.cjs';
最佳实践总结
- 首选方案:使用
moduleNameMapper
指向 CommonJS 版本 - 通用方案:配置
transformIgnorePatterns
允许转换 Axios - 及时更新:保持 Jest 和测试相关依赖为最新版本
- 注意缓存:修改配置后清除 Jest 缓存确保生效
重要提醒
在 Vue 项目中,避免添加 "type": "module"
到 package.json
,这可能导致其他配置文件(如 vue.config.js
)出现兼容性问题。
方案对比表
方案 | 优势 | 缺点 | 适用场景 |
---|---|---|---|
moduleNameMapper | 直接使用 CJS 版本,无需转换 | 与某些库(如 axios-mock-adapter)兼容性问题 | 简单项目,无需复杂模拟 |
transformIgnorePatterns | 正确转换 ESM 模块 | 稍微降低测试速度 | 通用解决方案,兼容性更好 |
命令行参数 | 无需修改配置文件,快速验证 | 只能应用在脚本调用时 | 临时解决方案或简单项目 |
更新 Jest | 解决根本性兼容问题 | 需要更新多个相关依赖 | 使用较旧 Jest 版本的项目 |
选择最适合您项目情况的解决方案即可解决 Axios 在 Jest 测试中的导入错误问题。