136

我有一个使用 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();
});

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

4

16 回答 16

105

还使用 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"
于 2020-10-06T10:06:27.460 回答
42

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

安装 Babel/preset-env

npm i -D @babel/preset-env

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

//babel.config.js
module.exports = {presets: ['@babel/preset-env']}
于 2019-12-25T20:52:48.473 回答
22

我通过将.babelrc文件迁移到babel.config.js! 令人震惊。

于 2020-05-08T10:27:29.240 回答
8

供日后参考,

在阅读了 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",
  }
};
于 2020-03-06T20:17:50.597 回答
7

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

不幸的是,我在这上面浪费了很多时间,但是我学到了很多关于 webpack 配置和 Babel 的知识。

于 2019-10-30T18:38:33.673 回答
5

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

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

或者

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

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

于 2020-04-09T06:40:59.433 回答
4

我很惊讶没有一个答案没有给出一个优雅的解决方案:

jest.config.js

module.exports = {
  ...,
  globals: {
    "ts-jest": {
      isolatedModules: true,
    },
  },
};

这会分别编译每个文件,从而避免无导出问题。

于 2022-01-20T12:42:11.127 回答
2

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

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

于 2021-08-25T21:23:06.270 回答
1

使用 Node 实验功能添加您的test脚本:package.json--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"
于 2021-12-02T12:33:33.433 回答
1

匹配的文件扩展名:

Todo.jsx我将在根目录中命名为./src/Todo/. 每当我将其更改为问题时Todo.js,问题就消失了。

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

于 2021-05-27T19:25:35.823 回答
0

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

{
  "compilerOptions": {
    "target": "es5",
    ...
  },
  ...
}
于 2020-04-26T19:16:00.230 回答
0

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

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

module.exports = {
  plugins: ['@babel/plugin-transform-modules-commonjs'],
  presets: [['@babel/preset-env', { targets: { node: 'current' } }]]
}
于 2021-10-02T17:50:29.003 回答
0

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

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

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

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

于 2021-11-03T19:34:47.347 回答
0

我通过将我的更改tsconfig.json为兼容的本机输出来解决它

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

这在每种情况下都不是理想的,但您可能对此没问题。

于 2021-12-21T23:53:32.983 回答
-1

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

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "modules": "commonjs"
      }
    ],
    "@babel/preset-react"
  ]
}
于 2021-10-13T13:01:20.453 回答
-4

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

在此处输入图像描述

于 2021-07-01T16:48:23.903 回答