"Cannot use import statement outside a module" with Axios

回答 6 浏览 1.5万 2022-10-05

我有一个 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,我不明白。

谁能建议在这里做什么?

knirirr 提问于2022-10-05
如果这个问题附有代码,那将会很有帮助。Rajashekhar Reddy 2022-10-05
您希望我特别附上什么代码?knirirr 2022-10-05
这就像您尝试导入的位置,您尝试导入的方式Rajashekhar Reddy 2022-10-05
谢谢。上面的问题中指定了“如何”。至于“哪里”,我不确定在这种情况下会有什么帮助。无论如何我都会把它放进去。knirirr 2022-10-05
6 个回答
#1楼
得票数 46

我通过添加以下内容,强迫jest导入commonjs axios构建,从而解决了这个错误:

  "jest": {
    "moduleNameMapper": {
      "axios": "axios/dist/node/axios.cjs"
    }
  },

给我的package.json。使用transformIgnorePatterns 的其他解决方案对我不起作用。

rcbevans 提问于2022-11-03
谁给这个人买杯啤酒吧,这是唯一对我有用的解决方案。遍及 StackOverflow 的 transformIgnorePatterns 解决方案没有用,我花了好几个小时。这是唯一一个成功的方案。谢谢 @rcbevansCheyne 2022-11-16
没错,我也一样!Kapil Raghuwanshi 2022-12-01
非常感谢:我在创建的新测试套件中遇到了这个错误,在这种情况下,将 axios 添加到 transformIgnorePatterns 是无用的。您的解决方案解决了我的情况amda 2022-12-16
谢谢,这对我也有用,但我必须将它添加到我的 jest.config.js 文件中。spetry 2023-01-06
#2楼
得票数 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 目录下的其他模块。

Junhyunny 提问于2022-10-15
Junhyunny 修改于2022-10-15
这对我不起作用rcbevans 2022-11-03
给我一些上下文Junhyunny 2022-11-03
同样在这里。对我没有用,我得到了同样的错误@Junhyunny SyntaxError: Cannot use import statement outside a modulequefro 2022-11-09
@quefro 给我一些背景信息Junhyunny 2022-11-09
#3楼
得票数 3

我有同样的问题,并且能够通过使用jest-mock-axios库来解决这个问题

Gerd Torf 提问于2022-10-10
#4楼
得票数 3

jest 的版本更新到 v29 修复了我项目中的这个问题。可能是您的jest 版本不兼容。

dpopp07 提问于2022-10-10
#5楼
得票数 1

我遇到了类似的问题,但错误是由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'

解决方案是简单地告诉jestaxios 要用babel 改造一下:

const esModules = ['lodash-es', 'axios'].join('|')

# add these entries in module.exports
transform: {
  [`^(${esModules}).+\\.js$`]: 'babel-jest',
},
transformIgnorePatterns: [`node_modules/(?!(${esModules}))`],

注意:我使用的是 Quasar Vue,这是它们的实现。

Covik 提问于2022-10-06
谢谢。目前,我已经通过降级 Axios 在本地解决了这个问题,但我会尝试看看是否有帮助。knirirr 2022-10-06
这对我不起作用。rcbevans 2022-11-03
#6楼
得票数 0

我有同样的问题,将 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;
  }
Melashu Amare 提问于2022-10-13