Jest无法解析es6:SyntaxError:意外的标记import

25

我正在尝试在我的webpack项目中设置Jest。当我运行测试时,Jest抱怨无法读取es6代码。Babel似乎没有转换我的测试文件。

我已经尝试了在互联网上找到的各种解决方案,但我仍然感到困惑。也许有更多Babel/Webpack知识的人可以查看我的配置并帮助我。

相关的package.json脚本:

{
    "test": "jest --no-cache --config config/jest.config.js"
}

相关的 package.json 依赖:

"@babel/core": "^7.2.2",
"@babel/plugin-proposal-class-properties": "^7.3.0",
"@babel/preset-env": "^7.3.1",
"@babel/preset-flow": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"babel-eslint": "^10.0.1",
"babel-jest": "^24.0.0",
"babel-loader": "^8.0.5",
"babel-plugin-styled-components": "^1.10.0",
"jest": "^24.0.0",
"webpack": "^4.29.0",
"webpack-cli": "^3.2.1",
"webpack-dev-server": "^3.1.14"

config/webpack.config.js:

entry: './src/index.js',
mode: isProduction ? 'production' : 'development',
devtool: isProduction ? 'none' : 'inline-source-map',
bail: true,
devServer: {
  contentBase: 'build',
  compress: true,
  port: 3000,
},
output: {
  path: path.resolve(__dirname, 'build'),
  filename: '[name].[chunkhash].js',
},
module: {
  rules: [
    {
      test: /\.js$/,
      exclude: /node_modules/,
      use: {
        loader: 'babel-loader',
        options: {
          cacheDirectory: true,
          presets: [
            '@babel/preset-env',
            '@babel/preset-react',
            '@babel/preset-flow',
          ],
          plugins: [
            'babel-plugin-styled-components',
            '@babel/plugin-proposal-class-properties',
          ],
        },
      },
    },
  ],
},
plugins: [
  new HtmlWebpackPlugin({
    template: 'src/index.html',
  }),
  new webpack.DefinePlugin({
    'process.env': JSON.stringify(process.env),
  }),
],

config/jest.config.js

module.exports = {
  verbose: true,
  rootDir: '../',
  setupFiles: ['./config/jest.setup.js'],
  transform: {
    '^.+\\.js?$': 'babel-jest',
  },

config/jest.setup.js

import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

Enzyme.configure({ adapter: new Adapter() });

jest错误: ● 测试套件运行失败

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.

...

Details:

/<...projectpath>/config/jest.setup.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import Enzyme from 'enzyme';
                                                                                         ^^^^^^

SyntaxError: Unexpected token import

我想要一个可用的测试运行器!我猜我的jest.config.js中的transform:babel-jest没有起作用...

3个回答

24

你需要完成两件事情:

  1. 创建一个Babel配置文件 (babel.config.js):

    这是必要的,因为 babel-jest 依赖于传统的 Babel 配置文件,而不是 webpack。自从版本 7 以来,Babel 支持将配置写成 JS 文件(如 babel.config.js)。

    当使用 JS Babel 配置文件(而不是例如 .babelrc)时,Jest 还会编译 node_modules 中的模块。据我所知,按照惯例,它必须与 Jest 配置文件放置在项目的根目录下。

    以下是一个基于你的 webpack.config.js 文件中的 Babel 选项的配置文件:

    // babel.config.js
    module.exports = {
      presets: [
        '@babel/preset-env',
        '@babel/preset-react',
        '@babel/preset-flow',
      ],
      plugins: [
        'babel-plugin-styled-components',
        '@babel/plugin-proposal-class-properties',
      ]
    }
    
  2. 安装 babel-core 桥接版本:

  3. npm install babel-core@7.0.0-bridge.0 --save-dev
    

    来自github.com/babel/babel-bridge

    这个仓库包含了我们所谓的“桥接”包,旨在为使用“babel-core”作为Babel 6对等依赖项的库的转换提供帮助。

    Babel 7转换到范围的问题在于,如果一个软件包依赖于Babel 6,他们可能想要添加支持Babel 7。因为Babel 7将发布为@babel/core而不是babel-core,维护者没有办法进行这种转换而不会产生破坏性变化。例如:


2
它能工作!你能解释一下为什么和如何吗?此外,只有当我的 babel.config.js 文件位于根目录时才能正常工作,如果我将其与 webpack.config.js 放在 config 文件夹中,它就会出现问题。这也很令人困惑... - Nicholas Mueller
1
@NicholasMueller 我更新了答案并附上了一些解释。 - sdgluck
2
@sdgluck 我在使用 create-react-app 创建的项目中遇到了同样的问题。由于配置是隐藏的,我不知道如何进行转译。我只知道 node_modules 中的 import 语句没有被转译(因此在 jest 中会抛出错误)。以上解决方案并没有起作用。有什么想法吗? - sookie
@sookie 在这种情况下,我相信你需要从 create-react-appeject,然后按照这个答案中的步骤进行操作。如果这样做不起作用,我建议你开一个新问题。 - sdgluck
1
非常感谢你。=) - Eduardo Henrique
3
你救了我的下午 (: - Mathiasfc

4
我遇到了类似的情况,我想用jest测试React组件.js文件,但它失败了,因为该组件导入了一个.css样式表。我正在使用Webpack的Babel。
根据@sdgluck所接受的答案,我必须添加一个babel.config.js:

1.

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

2. 我还安装了babel-jest作为开发依赖。

3. 然后我阅读了Jest Webpack指南

4. 这导致我在package.json中添加了一个“jest”属性,用于模拟文件和样式表:

"jest": {
    "moduleNameMapper": {
      "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
      "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js"
    }
  }

5. 接着我需要在指定路径下创建模拟文件(你可以使用任意路径,这里仅为示例):

// __mocks__/styleMock.js

module.exports = {};

// __mocks__/fileMock.js

module.exports = 'test-file-stub';

然后它正常工作了 :)


2
我有一些有用的信息,可以作为以后遇到这个问题的人的参考。
在jest配置中,默认情况下,transformIgnorePatterns是["/node_modules/", "\.pnp\.[^\/]+$"]
如果某些人的问题是由node_modules中的某些代码引起的,并且没有覆盖此值,则babel-jest仍然无法工作。
也许正确的值应该像这样:"/node_modules/(?!(your-third-part-es-module-code|others-es-lib))"。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接