“不能在模块外使用导入语句”与 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 ,我不明白。

谁能建议在这里做什么?

stack overflow "Cannot use import statement outside a module" with Axios
原文答案

答案:

作者头像

The 1.x.x version of axios changed the module type from CommonJS to ECMAScript.

The 0.x.x version of axios index.js file
module.exports = require('./lib/axios');
The 1.x.x version of axiox index.js file
import axios from './lib/axios.js';
export default axios;

Basically, jest runs on Node.js environment, so it uses modules following the CommonJS. If you want to use axios up to 1.x.x, you have to transpile the JavaScript module from ECMAScript type to CommonJS type. Jest ignores /node_modules/ directory to transform basically.

So you have to override transformIgnorePatterns option. There are two ways to override transformIgnorePatterns option.

jest.config.js

If your vue project uses jest.config.js file, you add this option.

module.exports = {
  preset: "@vue/cli-plugin-unit-jest",
  transformIgnorePatterns: ["node_modules/(?!axios)"],
  ...other options
};

package.json

If your vue project uses package.json file for jest, you add this option.

{
  ...other options
  "jest": {
    "preset": "@vue/cli-plugin-unit-jest",
    "transformIgnorePatterns": ["node_modules\/(?!axios)"]
  }
}

This regex can help you to transform axios module and ignore others under node_modules directory.

作者头像

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

作者头像

我遇到了类似的问题,但错误是由 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,这是他们的实现。

作者头像

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

作者头像

我遇到了同样的问题,将 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;
  }
作者头像

我能够通过强制 jest 通过添加导入 commonjs axios 构建来修复此错误

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

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