babel-jest无法处理模块

时间:2017-02-14 12:50:24

标签: babeljs jestjs es6-modules

我正在尝试在基于React的项目上设置Jest,该项目使用ES6模块。但是我似乎遇到了ES6模块的问题,我正在使用babel-jest并相信我已正确设置(Jest会自动检测到它)。

Jest似乎没有使用ES6导入的问题,但是只要它在其中一个导入的模块中的导入语句上命中它就会窒息。就好像它只是转发初始测试脚本而不是任何导入的模块。我尝试了各种配置,并尝试搜索谷歌没有运气。没有任何导入的运行测试工作正常。

这是错误:

({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import Predications from './predications';
                                                                                         ^^^^^^
SyntaxError: Unexpected token import

以下是config的相关部分:

jest.conf.json

{
  "testRegex": "\/test\/spec\/.*\\.js$",
}

.babelrc

{
  "presets": ["es2015", "stage-0", "react"]
}

测试脚本

import React from 'react';
import { mount, shallow } from 'enzyme';
import Slider from 'react-slick';
import Carousel from '../../client/components/carousel/carousel.js'; // test chokes on when I include this module

describe('carousel component', () => {
  it('is a test test case', () => {
    expect(1 + 2).toEqual(3);
  });
});

更新

正如所建议的,我已经尝试在没有jest.conf.js的情况下运行测试,但是为了让Jest找到我的测试需要testRegex,我尝试将测试移动到默认测试目录,但它们仍然失败。

我想澄清测试本身运行正常,问题似乎是我导入的模块之一使用ES6,在上面的例子中,如果我不导入我的轮播组件,测试运行正常因为我导入测试choke在该文件中的import语句。似乎导入的模块没有被编译。

更新#2

经过一些调查后,问题似乎是babel没有在node_modules中转换ES6。我在这里创建了一个示例repo来演示:https://github.com/jamiedust/babel-jest-example

我知道第三方模块应该处理他们自己的转换,但是我们有许多模块,这些模块托管在我们自己的npm注册表中并在项目之间重复使用,在这些情况下,Webpack处理转换,用于Jest测试我们需要Babel编译这些node_modules,或者利用我们的webpack设置来为我们做这件事。

解决方案

在package.json(或Jest配置文件)中添加以下配置。

"jest": {
  "transformIgnorePatterns": [
    "/node_modules/(?!test-component).+\\.js$"
  ]
}

5 个答案:

答案 0 :(得分:10)

默认情况下,node_modules会忽略babel-jest中的所有代码,请参阅Jest配置选项transformIgnorePatterns。我还创建了PR on your example repo,因此您可以看到它正常工作。

虽然这有效,但我发现它在包含ES模块的许多依赖项的实际应用程序中非常慢。 Jest代码库的方法略有不同,因为您可以在“babel-jest转换依赖项”中找到 (抱歉,我不会发布超过2个网址) 。这在Windows上也可能需要更长的时间,请参阅“空白回购时需要10秒”

如果进行“单元”测试,模拟可能是更好的方法。

答案 1 :(得分:2)

您可以尝试将transform-es2015-modules-commonjs插件添加到您的babel配置文件中以进行测试。这是一个示例配置文件,它告诉babel仅在测试环境中转换模块。你可以把它放在你的预设下面:

{
  "presets": [
    "react",
    ["es2015", {"modules": false, "loose": true}]
  ],
  "env": {
    "test": {
      "plugins": ["transform-es2015-modules-commonjs"]
    }
  }
}

你可以在这里阅读插件:

https://www.npmjs.com/package/babel-plugin-transform-es2015-modules-commonjs

然后,在命令行上运行Jest测试时,指定NODE_ENV = test(您可能需要在更改babel配置后第一次将--no-cache标志添加到命令,因为Jest缓存了babel输出,但在那之后你可以把它关掉:

NODE_ENV=test jest --no-cache

我在Frontend Masters的Brian Holt的React研讨会上了解到了这个问题。 https://frontendmasters.com/courses/

答案 2 :(得分:1)

我遇到了同样的问题(node_module没有被babel-jest描述),但却无法解决。

相反,我最终通过模拟node_module取得了成功,如此处所述https://facebook.github.io/jest/docs/manual-mocks.html

注意:在__mocks__子文件夹中设置模拟对我来说不起作用。所以我将模拟作为jest.mock()函数的第二个参数传递。类似的东西:

    jest.mock('your_node_module', () => {})

答案 3 :(得分:1)

另一个可能的原因。 Babel现在忽略了node_modules中的.babelrc并使用了依赖项提供的那个。如果您可以控制依赖项,则必须向其添加.babelrc,而babel会对其使用这些设置。

如果您的依赖项和项目使用不同的babel版本或模块,则可能会导致问题。

答案 4 :(得分:1)

面对同样的问题,请按照以下步骤解决,

  1. 安装babel-jest
  2. 在jest配置中添加此配置
       transform: {
           '^.+\\.js?$': require.resolve('babel-jest')
       }
  1. 确保您存在babel.config.js(您的配置可能与下面提供的配置不同)
    module.exports = {
      "env": {
        "test": {
          presets: [
            [
              '@babel/preset-env',
              {
                targets: {
                  node: 'current',
                },
              },
            ],
          ]
        }
      }
    };