【问题标题】:babel-jest doesn't handle ES6 within modulesbabel-jest 不处理模块内的 ES6
【发布时间】:2017-07-02 18:34:05
【问题描述】:

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

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

这是错误:

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

以下是相关配置:

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 的情况下运行测试,但是需要 testRegex 才能让 Jest 找到我的测试,我尝试将测试移动到默认测试目录,但它们仍然失败。

我想澄清一下,测试本身运行良好,问题似乎是我导入的模块之一使用 ES6,在我上面的示例中,如果我不导入我的轮播组件,测试运行良好,尽快当我导入该文件中的导入语句时,测试会阻塞。似乎导入的模块没有被转译。

更新 #2

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

我知道第三方模块应该处理他们自己的转译,但是我们有许多模块托管在我们自己的 npm 注册表上并在项目之间重用,在这些情况下,Webpack 处理转译,用于 Jest 测试我们需要这些 node_modules 由 Babel 转译,或者利用我们的 webpack 设置为我们执行此操作。

解决方案

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

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

【问题讨论】:

  • 当您从开玩笑设置中删除 transform 部分时会发生什么。这在简单的情况下不需要。
  • @AndreasKöberle 我得到了同样的错误,是的,你的权利我似乎不需要它
  • 你试过在没有jest.conf.js的情况下运行吗?它应该可以在没有额外配置的情况下工作
  • 我怀疑 textRegex 和/或 transform 是问题的根源
  • 你可以在这里验证github.com/MinimalNoise/persist-lead-service,测试完全通过es-modules(虽然没有jsx)没有任何特定的jest配置

标签: babeljs jestjs es6-modules


【解决方案1】:

您可以尝试将 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/

【讨论】:

  • 谢谢@A。 Cookro 我之前尝试过,只是再次尝试并没有运气,babel 似乎仍然在忽略 node_modules 中的文件。
  • 在尝试了 10 种不同的方法之后,这个解决方案是唯一一个在 ES6 导入中表现正常的解决方案
【解决方案2】:

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

相反,我终于通过模拟 node_module 成功了,就像这里描述的 https://facebook.github.io/jest/docs/manual-mocks.html

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

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

【讨论】:

  • 谢谢,我会试试这个解决方案,让你知道效果如何。
【解决方案3】:

默认情况下,babel-jest 会忽略 node_modules 中的任何代码,请参阅 Jest 配置选项 transformIgnorePatterns。我还创建了一个PR on your example repo,所以你可以看到它在工作。

虽然这可行,但我发现它在具有大量包含 ES 模块的依赖项的实际应用程序中非常慢。 Jest 代码库对此略有不同,您可以在babel-jest transforming dependencies 中找到。这在 Windows 上也可能需要更长的时间,请参阅 Taking 10 seconds on an empty repo

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

【讨论】:

  • 谢谢,我还没来得及查看 PR,但我会​​的。我曾尝试使用许多 Jest 选项,包括我相信的 transformIgnorePatterns,但我可能做错了什么,所以会检查一下。
  • 终于有时间检查 PR 并接受了,我现在可以正常运行测试了。碰巧我们暂时坚持使用我们的 Karma/Jasmine 堆栈。为了其他人的利益,以下配置可以解决此问题: `"jest": { "transformIgnorePatterns": [ "/node_modules/(?!test-component).+\\.js$" ] },
  • @jamiedust 如果贡献者分享他们的观点,他们可能希望确保将给定的信息传达给其他人。删除包含相关 PR 的存储库对任何人都没有帮助。
  • @oyilmaztekin 这是一个公平的观点,我在删除该回购时没有考虑到这一点,抱歉。但是请注意,我确实在我的最后一条评论中放置了相关的配置:在 package.json "jest": { "transformIgnorePatterns": [ "/node_modules/(?!test-component).+\\.js$" ] }
【解决方案4】:

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

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

【讨论】:

    【解决方案5】:

    遇到同样的问题,按照步骤解决,

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

    【讨论】:

      猜你喜欢
      • 2018-03-20
      • 1970-01-01
      • 2020-06-07
      • 1970-01-01
      • 2020-04-02
      • 2017-09-08
      • 2018-09-14
      • 2016-11-20
      • 2017-10-18
      相关资源
      最近更新 更多