【问题标题】:How to resolve "Cannot use import statement outside a module" in jest如何解决“无法在模块外使用导入语句”的问题
【发布时间】:2020-02-25 01:13:37
【问题描述】:

我有一个使用 TypeScript、Jest、Webpack 和 Babel 构建的 React 应用程序(不使用 Create React App)。尝试运行yarn jest 时,出现以下错误:

我已尝试删除所有软件包并重新添加它们。它不能解决这个问题。我看过类似的问题和文档,但我仍然误解了一些东西。我什至遵循另一个指南从头开始设置此环境,但我的代码仍然收到此问题。

依赖包括...

"dependencies": {
  "@babel/plugin-transform-runtime": "^7.6.2",
  "@babel/polyfill": "^7.6.0",
  "babel-jest": "^24.9.0",
  "react": "^16.8.6",
  "react-dom": "^16.8.6",
  "react-test-renderer": "^16.11.0",
  "source-map-loader": "^0.2.4"
},
"devDependencies": {
  "@babel/core": "^7.6.0",
  "@babel/preset-env": "^7.6.0",
  "@babel/preset-react": "^7.0.0",
  "@types/enzyme": "^3.9.2",
  "@types/enzyme-adapter-react-16": "^1.0.5",
  "@types/jest": "^24.0.13",

组件的导入行...

import * as React from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import HomePage from "./components/pages";
import {
  Footer,
  Header,
  Navigation,
} from "./components/shared";

测试文件....

import * as React from "react";
import * as renderer from "react-test-renderer";
import App from "../App";

it("Renders the Footer correctly", () => {
  const tree = renderer
    .create(<App />)
    .toJSON();
  expect(tree).toMatchSnapshot();
});

我希望能够在我的组件中使用命名导入,而不会导致测试失败。如果我只通过我的解决方案使用默认导入,它似乎可以解决问题,但我宁愿不走那条路。

【问题讨论】:

  • 仅供参考,我在为 Jest 设置自定义 TestSequencer 时遇到了这个问题,我刚刚切换到使用 require 而不是 import,仅针对这个文件。
  • 这也可能是由于环境变量的问题而发生的。在此处查看我的其他但相关的答案:stackoverflow.com/a/63749183

标签: reactjs jestjs babeljs babel-jest ts-jest


【解决方案1】:

也使用 Babel、Typescript 和 Jest。有同样的失败,让我疯狂了几个小时。 最后为测试创建了一个新的babel.config.js 文件。有一个很大的.babelrc,不管我对它做了什么,它都没有被开玩笑地捡起来。主应用仍然使用.babelrc,因为它会覆盖babel.config.js 文件。

安装 jest、ts-jest 和 babel-jest:

npm i jest ts-jest babel-jest

babel.config.js(仅供笑话使用)

module.exports = {presets: ['@babel/preset-env']}

jest.config.js

module.exports = {
  preset: 'ts-jest',
  transform: {
    '^.+\\.(ts|tsx)?$': 'ts-jest',
    "^.+\\.(js|jsx)$": "babel-jest",
  }
};

package.json

  "scripts": {
    "test": "jest"

【讨论】:

  • 谢谢!这就像一个魅力。必须将我的 .babelrc 转换为 babel.config.js 才能做到这一点,但这一切都成功了!
  • 对我来说,打字稿文件的新转换出现了问题,通过添加 js 转换来使用 babel-jest 即添加 "^.+\\.(js|jsx)$": " babel-jest" 在 jest 配置 js 文件中进行转换
  • 有效,别忘了也安装@babel/preset-env?
  • 非常感谢,这也给我带来了很多麻烦,您的解决方案花了几秒钟的时间才包含在内,就像其他人所说的那样 - 它就像魅力一样。
【解决方案2】:

使用 Babel 转译这些 JS 模块,您将能够使用 es6 编写测试。

安装 Babel/preset-env

npm i -D @babel/preset-env

使用预设创建一个 babel 配置文件

//babel.config.js
module.exports = {presets: ['@babel/preset-env']}

【讨论】:

  • 直接简洁,谢谢!对于我在tsdx 上派生的项目,这是诀窍(以及@babel/preset-react)。
  • 谢谢,这解决了我的问题
【解决方案3】:

我通过将.babelrc 文件迁移到babel.config.js 解决了这个问题!令人震惊。

【讨论】:

  • 这是我的问题!忘记复制 babel 配置了!谢谢:)
【解决方案4】:

供日后参考,

在阅读了 Logan Shoemaker 的回答后,我通过使用下面的 jest 配置解决了这个问题。

module.exports = {
  verbose: true,
  setupFilesAfterEnv: ["<rootDir>src/setupTests.ts"],
  moduleFileExtensions: ["js", "jsx", "ts", "tsx"],
  moduleDirectories: ["node_modules", "src"],
  moduleNameMapper: {
    "\\.(css|less|scss)$": "identity-obj-proxy"
  },
  transform: {
    '^.+\\.(ts|tsx)?$': 'ts-jest',
    "^.+\\.(js|jsx)$": "babel-jest",
    "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/file.js",
  }
};

【讨论】:

  • 我的 Jest 配置只缺少 moduleDirectories: ["node_modules", "src"], 其中我添加了,一切都按预期开始工作。谢谢
【解决方案5】:

解决方案:我的命名导入来自 index.js 文件,我相信 ts-jest 需要它们作为 index.ts 文件(我使用的是 Typescript)。如果其他人遇到此错误,请检查您是否破坏了文件扩展名。

很遗憾,我在这方面浪费了很多时间,但我学到了很多关于 webpack 配置和 Babel 的知识。

【讨论】:

  • 你是如何解决其他模块中index.js的问题的?
  • 我花了两个小时解决这个错误。好吧,看完这个答案,我现在想哭T_T。我正在从 js 迁移到 typescript,但忘记将“.js”重命名为“.ts”
【解决方案6】:

如果你使用的是 babel 6,试试这个

  1. babel.config.js的插件部分添加@babel/plugin-transform-modules-commonjs

  1. 对于我的情况,导入问题是由于将反应文件添加到transfromIgnorePatterns

"transformIgnorePatterns": ["/node_modules/(?!react-file-drop)"]

【讨论】:

  • 就我而言,仅帮助transformIgnorePatterns: ['/node_modules/(?!react-hls-player)'],
【解决方案7】:

我通过在 package.json 运行器中的 run 语句后简单地附加模式来修复它

"test": react-scripts test --transformIgnorePatterns "node_modules/(?!my-library-dir)/"

【讨论】:

    【解决方案8】:

    匹配文件扩展名:

    我在根目录中导入了一个名为 Todo.jsx 的文件作为 ./src/Todo/。每当我将其更改为 Todo.js 时,问题就消失了。

    免责声明:我不确定将文件扩展名设置为 jsxjs 的组件的要求是什么。它根本没有影响到我,但我可以想象它可能会与智能感知或 sn-ps 混淆。

    【讨论】:

      【解决方案9】:

      Typescript、Jest、VueJS/VueCli 3 都遇到了同样的问题,正常构建没有问题。只发生在 Jest 身上。我挣扎了好几个小时寻找。但实际上没有答案有效。就我而言,我依赖于我自己的 typescript 包,我在 tsconfig.json 中指定了 "target": "es6"。这是根本原因。所以解决方法就是简单地将依赖的(不是同一个项目)改回es5 tsconfig.json:

      {
        "compilerOptions": {
          "target": "es5",
          ...
        },
        ...
      }
      

      【讨论】:

      • 你改变了什么?
      • 对不起,我原来的帖子中的错误。我在依赖模块中使用 es6 。这就是问题的根本原因。我改回es5后,问题解决了
      【解决方案10】:

      我个人遵循@ajwl 设置,但发现jest.config.jssetupFiles: 部分内的jsdom-worker 触发了同样的错误。删除后,我的测试就通过了。

      附:我的 babel.config.js 有点不同,因为我有一个 Vuejs (v2) SPA(与 Vitejs 捆绑):

      module.exports = {
        plugins: ['@babel/plugin-transform-modules-commonjs'],
        presets: [['@babel/preset-env', { targets: { node: 'current' } }]]
      }
      

      【讨论】:

        【解决方案11】:

        问题很可能是 jest 本身不支持 esmodules。如果您的打字稿目标是 es6 或更高版本,这可能会导致问题。

        如果您正在测试构建的 typescript 输出,您可以在转译时简单地添加 module=commonjs 标志。这样,您的代码就可以在 es6 或更高版本上运行,并且仍然可以在 Jest 上运行。

        "scripts": {
          "test": tsc --module commonjs && jest {your-output-folder}/
        }
        

        这样做的好处是我不必添加任何额外的 babel 依赖项或特殊的 jest runner :)

        【讨论】:

          【解决方案12】:

          package.json 中添加您的 test 脚本,并使用 Node 实验功能:--experimental-vm-modules

          这样你就不需要 babel 或其他依赖了。

          例子:

          "test": "NODE_OPTIONS='--experimental-vm-modules --experimental-specifier-resolution=node' jest"
          

          如果您收到此错误:zsh: command not found: jest,请尝试使用 node 传递 jest.js,如下所示:

          "test": "NODE_OPTIONS='--experimental-vm-modules --experimental-specifier-resolution=node --trace-warnings' node node_modules/jest/bin/jest.js --detectOpenHandles"
          

          【讨论】:

            【解决方案13】:

            我通过将我的 tsconfig.json 更改为兼容的本机输出解决了这个问题

            "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
            

            这在每种情况下都不是理想的,但您可能会接受。

            【讨论】:

              【解决方案14】:

              在主目录创建.babelrc并添加此代码并安装这些包 @babel/core、@babel/preset-env 和 @babel/preset-react

              {
                "presets": [
                  [
                    "@babel/preset-env",
                    {
                      "modules": "commonjs"
                    }
                  ],
                  "@babel/preset-react"
                ]
              }
              

              【讨论】:

                【解决方案15】:

                如果您使用的是 TypeScript,并且您有一个 tsconfig.json 文件,请尝试删除 "module": "esnext"(如果您正在使用它)

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2020-03-11
                  • 2020-01-31
                  • 2023-02-08
                  • 2021-01-05
                  • 1970-01-01
                  • 2021-10-02
                  • 1970-01-01
                  • 2021-05-29
                  相关资源
                  最近更新 更多