"Cannot use import statement outside a module" with Axios
我有一个 Vue.js 应用程序,其中包含两个文件:
import axios from "axios"
这些文件位于应用程序内的 src/lib 中,并在其第一行包含 import 语句。
在 Github 上运行测试会导致安装 Axios 1.0.0,无论 package.json 说什么,现在任何涉及这些文件的测试都会失败并出现上述错误。
将语句更改为 const axios = require("axios")
也会失败; node_modules/axios/index.js 在第 1 行包含一个 import 语句,并在那里抛出异常。
对于此类问题,我经常看到的一个建议是将 "type": "module"
添加到 package.json(与 src/ 处于同一级别)。这会导致所有测试失败,并要求将 vue.config.js 重命名为 vue.config.cjs。这样做让我得到错误: Error: You appear to be using a native ECMAScript module configuration file, which is only supported when running Babel asynchronously
,我不明白。
谁能建议在这里做什么?
我通过添加以下内容,强迫jest导入commonjs axios构建,从而解决了这个错误:
"jest": {
"moduleNameMapper": {
"axios": "axios/dist/node/axios.cjs"
}
},
给我的package.json
。使用transformIgnorePatterns
的其他解决方案对我不起作用。
transformIgnorePatterns
解决方案没有用,我花了好几个小时。这是唯一一个成功的方案。谢谢 @rcbevans
- Cheyne 2022-11-16
transformIgnorePatterns
是无用的。您的解决方案解决了我的情况
- amda 2022-12-16
1.x.x 版本的 axios 将模块类型从 CommonJS 更改为 ECMAScript。
0.x.x版本的axios index.js文件
module.exports = require('./lib/axios');
1.x.x版本的axiox index.js文件
import axios from './lib/axios.js';
export default axios;
基本上,jest 在 Node.js 环境中运行,因此它使用遵循 CommonJS 的模块。
如果你想使用 axios 到 1.x.x,你必须将 JavaScript 模块从 ECMAScript 类型转换为 CommonJS 类型。
Jest 基本忽略/node_modules/
目录转换。
所以你必须覆盖transformIgnorePatterns
选项。
有两种方法可以覆盖transformIgnorePatterns
选项。
jest.config.js
如果你的 vue 项目使用 jest.config.js
文件,你添加这个选项。
module.exports = {
preset: "@vue/cli-plugin-unit-jest",
transformIgnorePatterns: ["node_modules/(?!axios)"],
...other options
};
package.json
如果你的 vue 项目为jest使用 package.json
文件,你可以添加这个选项。
{
...other options
"jest": {
"preset": "@vue/cli-plugin-unit-jest",
"transformIgnorePatterns": ["node_modules\/(?!axios)"]
}
}
此正则表达式可以帮助您转换 axios 模块并忽略 node_modules 目录下的其他模块。
我有同样的问题,并且能够通过使用jest-mock-axios库来解决这个问题
将 jest
的版本更新到 v29 修复了我项目中的这个问题。可能是您的jest
版本不兼容。
我遇到了类似的问题,但错误是由jest
引起的。
所有尝试导入 axios
的测试都失败并抛出相同的异常:
Test suite failed to run
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
• If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
/monorepo/node_modules/axios/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import axios from './lib/axios.js';
^^^^^^
SyntaxError: Cannot use import statement outside a module
1 | import { describe, expect, it } from '@jest/globals'
> 2 | import axios from 'axios'
解决方案是简单地告诉jest
,axios
要用babel
改造一下:
const esModules = ['lodash-es', 'axios'].join('|')
# add these entries in module.exports
transform: {
[`^(${esModules}).+\\.js$`]: 'babel-jest',
},
transformIgnorePatterns: [`node_modules/(?!(${esModules}))`],
注意:我使用的是 Quasar Vue,这是它们的实现。
我有同样的问题,将 axios 更改为 fetch 时它工作正常。
axios(失败)
try {
const response = await axios("api/fruit/all");
return response.data;
} catch (error) {
return error;
}
获取(工作正常)
try {
const response = await fetch("api/fruit/all",{method:"GET"});
const data = await response.json();
return data;
} catch (error) {
return error;
}