babel-jest 不处理模块内的 ES6
Posted
技术标签:
【中文标题】babel-jest 不处理模块内的 ES6【英文标题】:babel-jest doesn't handle ES6 within modules 【发布时间】: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
配置
【参考方案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】:遇到同样的问题,按照步骤解决,
-
安装 babel-jest
在 jest config 中添加此配置
transform:
'^.+\\.js?$': require.resolve('babel-jest')
-
确保存在 babel.config.js(您的配置可能与下面提供的不同)
module.exports =
"env":
"test":
presets: [
[
'@babel/preset-env',
targets:
node: 'current',
,
,
],
]
;
【讨论】:
以上是关于babel-jest 不处理模块内的 ES6的主要内容,如果未能解决你的问题,请参考以下文章