Jest: 对 RequireJS 的支持

创建于 2014-05-15  ·  84评论  ·  资料来源: facebook/jest

如果我理解正确的话,目前没有办法将它与 RequireJS 而不是 CommonJS 风格的 require() 一起使用。 是否有计划增加对 RequireJS 的支持? 它甚至可行吗?

最有用的评论

babel-plugin-transform-amd-to-commonjs可以证明对解决 Jest+AMD 的问题很有用,特别是如果你已经在使用类似 babel-jest 的东西。

我已经建立了一个示例项目,它展示了如何通过在测试环境中运行转换来让 Jest 透明地需要 AMD 文件。

我不确定这种方法在实际项目中的细节——尤其是在 Jest/RequireJS/Webpack/etc 之间进行配置共享的好方法。 对 .js 配置文件的 Jest 支持将是朝着更可重用的解决方案迈出的一步(请参阅 https://github.com/facebook/jest/issues/2140)。

所有84条评论

++

支持 Jest 的模块系统附加组件(如 require.js、es6 模块等)在我们的路线图中,但不幸的是,我们还没有完全做到。

不过,让我们让这个问题保持开放以跟踪这方面的进展——我认为支持 require.js 加载器会非常有用

@jeffmo webpack支持 commonjs/es6/amd。 如果我们可以将 jest 作为插件引入,我们可能会免费获得所有这些东西。

++

我们在一个大组织有很多项目并计划使用 jest,但我们 100% 需要 js。 任何关于requirejs集成的eta?

++

我也想试试玩笑,但我目前正在进行的项目正在使用 RequireJS。

:+1:

有人建议用这个做垫片,有人试过吗?

https://github.com/Jakobo/redefine

_可行的警告_。 我在一些随机 repo中使用nodefy实现了一个小构建,可以作为

石蕊测试:您的 AMD 模块别名与 node_modules 下的相应模块一致。 如果石蕊测试失败,但你很绝望,你可以 nodefy 纯 AMD 模块和/或向 node_modules 添加符号链接,但这个想法让我很难过。 从我的角度来看,我使用的外部设备倾向于实现 UMD 并通过 npm 安装到与我的 AMD 别名一致的名称——没什么大不了的。

(我在 nodefy 之前检查了 uRequire,但CommonJS 模板在功能上与 nodefy 相同——我将使用目标工具。我还检查了 amdefine,但 jest 在 'require' 上使用正则表达式匹配——也许有一个匿名 AMD角度?总有 UMD,但是用分散的document引用编码 UMD 听起来很不礼貌。)

+1

++

我们在所有新的客户端代码中都使用了 react、backbone 和 requirejs。 我希望能够使用 jest 并减轻测试反应的一些痛苦。 把事情降到单位级别会很好。 目前,我们正在使用 rspec 和 webdriver 完成对 react 代码的测试。 虽然这可行,但由于显而易见的原因,它并不理想。

有什么实用的解决方法吗? 我遇到的主要问题是包装反应组件的定义语句。

+1

@petehunt让我开始使用 Webpack,所以这也是需要考虑的事情。

+1

有人可以指出一个 jasmine/webpack 或 jest/webpack 运行具有代码覆盖率的浏览器测试的示例吗?

++

我们什么时候可以期待对 requirejs 的支持?

+1

+1

+1

+1

+1

+1

如果您使用 module.exports 而不是 return 进行定义调用,则可以将其添加到预处理器中。

对我有用:thumbup:

// preprocessor.js
var ReactTools = require('react-tools');
module.exports = {
  process: function(src) {
    if (/define\(.*?\{/.test(src)) {
      //Remove AMD ceremony for use without require.js or almond.js
      src = src.replace(/define\(.*?\{/, '')
        .replace(/(}\);|}\))$/,'');
    }

    return ReactTools.transform(src);
  }
};

++

+1

+1

+1 RequireJS 支持

+1

@charliedowler您介意再说明一下这种方法吗。 我正在尝试并遇到几个问题。 我开始添加

if (typeof(module) == 'object' && module.exports) { module.exports = <my_element>;  }

然而,我正在使用return ,所以我从预处理器中得到一个解析器错误。 我想我可以通过扩展 RegEx 以匹配最后一次返回来摆脱困境。 但它似乎根本不起作用。 我不断收到“非法退货声明”错误。 可能是表达式有问题,它没有捕捉到它。

if (/define\(.*?\{/.test(src)) {
  src = src.replace(/(define\(.*?\{|return.*[\s]}\);?$)/g,'');  
}

有没有办法让我将src写入标准输出? 一个简单的 console.log 不起作用。

最后,假设我让所有这些工作。 你是如何处理依赖关系的? 比如 React?

+1

啊! 我一直在玩(并且非常喜欢开玩笑)。 今天尝试将其拉入实际项目,发现没有 requireJS 支持 :sob: ... 对所有当前“真实”项目的交易破坏者。 确实可悲。 这肯定是一个令人兴奋的想法!

:+1:

+1

+1

:+1:

:竖起大拇指:

:+1:

:+1:

所以我通过使用 webpack 将我的 AMD 模块和测试一起编译来解决了这个问题。 这使我还可以在我的测试中使用各种额外的加载器。 https://github.com/ninjapanzer/Backbone-Flux-React-Webpack

:+1:

+1

+1

+1

感谢您报告此问题并感谢您的耐心等待。 我们已通知核心团队有关此问题的更新。 我们正在寻找未来 30 天内的回复,否则该问题可能已关闭。

+1

@facebook-github-bot-4 请这样做!

+1

+1

++

我一直在研究Jestpack ,它可以替代 Jest 的“HasteModuleLoader”以支持 Webpack。 因此,这意味着您可以使用 Webpack 支持的任何模块系统,包括 AMD。

附带说明一下,除了那些使用 FB 风格的 haste 模块的大型(ish)开源项目,是否有人知道使用 Jest 的任何大型(ish)开源项目,因为它对于测试 Jestpack 的性能非常有用?

我也一直在研究jest-requirejs ,这更像是对标准 jest 预处理器的尝试,它分析项目main.js配置文件,然后执行deamdify ,删除define包装器,根据 main.js 指定的 baseUrl 和路径的详细信息重写 require 路径,然后像往常一样将转换后的文件传递给 jest。

仍在研究插件/加载器语法,并在测试环境中重写jest.dontMock("")jest.setMock("")require.requireActual("")路径。

嘿伙计们,这真是太棒了。 我喜欢 Jestpack 的想法,我一直想让支持额外的模块解析器变得更容易。 最后,我还想修改网站并推荐 Jestpack 之类的解决方案,作为入门指南的一部分(我脑子里已经有了 :))。 @richardscarrott@sterpe如果您需要任何东西,请告诉我。

还抄送@mwolson@ColCh

(对其他人:请停止点赞评论,这没有帮助。如果您想要为开玩笑而构建的东西,请发送拉取请求。代码赢得争论!就我个人而言,我不能仅仅因为社区中的人们需要它们而优先考虑功能,而我不要使用我自己的_所有模块加载器_。)。

Jestpack 很有趣,尽管我不喜欢必须为每个测试创建一个入口点。 https://github.com/Ticketmaster/jest-webpack-alias更通用地解决了这个问题,代价是一些预处理,以及由于重新实现 webpack 的模块解析代码而可能尚未发现的错误。

另外:入门指南可能应该提到限制预处理器运行的文件是一个好主意,如果有的话,否则会大大减慢测试运行的速度。

预处理器只运行一次,您可以提供缓存键功能。 如果文件没有改变,jest 不会重新运行你的预处理器。

可能是这样,但即使是第一次运行也足以增加大约 10 秒的时间来执行我们的测试套件。

同意这并不快。 在 FB,第一次运行所需的时间几乎是后续运行的两倍,但我个人认为没有其他方法可以解决这个问题——我们在 FB 使用 babel 和其他自定义转换; 我们无法在没有预处理器的情况下运行测试 :)

在开发 requirejs 预处理器时,预处理器缓存让我很痛苦。 我主要还是使用[email protected]我相信它没有缓存?

0.5 应该可以正常工作!

Webpack 在 dev-watch 模式下非常快。

因为:

  1. Webpack 将它们的运行时保存在内存中(无需重新加载)
  2. 编译后的源代码也位于内存中。

所以,在我的 Jest 预处理器中,我只实现了 (2) 点。

在缩短,在玩笑和的WebPack的顶部封装(Jestpack吧...)将解决与性能的所有问题-只是不停玩笑和运行时的WebPack在内存中,内存FS编译的文件,并在内存FS执行测试用例。

这就是我的观点...

但是我们现在又遇到了一个麻烦:暂时无法将内存 FS注入到Jest中。

我考虑过使用私有 Jest 缓存 API - 将编译后的源代码直接注入缓存。 可能是黑客,所以我在这里错了: jest-webpack/issues/4#issuecomment-98623189

啊,我应该提一下,使用Webpack作为预处理器的Karma 的工作速度也很慢。 所以,我认为主要的性能下降是因为文件之间的 webpack 运行时重新加载。

@cpojer我认为您打算最终使模块加载器可配置,因为它已经被选择了,所以我想我会用 Jestpack 给它一个刺。 我遇到的唯一真正的问题是了解为 node_modules https://github.com/facebook/jest/issues/509发现手动模拟的逻辑,我最终只是选择了一个对我有意义的解决方案,但如果你能够提供有关该问题的任何见解,将 Jestpack 的模块加载器与 HasteModuleLoader 对齐会很好。

@mwolson Jestpack 每个测试文件使用单独的入口点的原因是为了确保它仍然可以利用 Jest 的多进程。

实际上, moduleLoader已经可以指定为配置的一部分。

++

我们也想要这个。 Jest 似乎是一款很棒的软件,但由于没有 RequireJS 支持,我们无法重写所有内容。

+1

社区中是否有人对此感兴趣? 我很乐意通过这个来支持人们并制作一个官方的 Jest 插件。 我们不太可能很快在 FB 对此进行大量投资。 Jest 团队非常小(1.5 人),很遗憾,我们无法开发所有这些功能。

基于 JavaScript 社区和标准的当前状态,似乎 require js 本身在编写 JavaScript 代码方面没有广阔的前景。 我们现在在 ES2015 中有一个标准化的模块系统。 Babel 和 Jest 现在已经完全集成并且可以很好地协同工作。 我会建议任何人切换到 CommonJS 或 ES2015 模块,这将为您提供更多开箱即用的工具。

require JS 也有一个关于如何将 CommonJS 转换为 require.js 的文档,可用于生产部署,请参阅: http ://requirejs.org/docs/commonjs.html

就我个人而言,我认为使用 require JS 编写代码没有任何好处。 我也很乐意帮助编写一个可以帮助将需要 JS 代码库转换为 CommonJS 的codemod 。 另一个挑战可能是为 CommonJS babel 插件编写一个 requireJS 并将其提取到 Jest 的预处理器中。

@cpojer我在这里的预处理器方法有点成功https://github.com/sterpe/jest-requirejs/blob/master/index.js但到目前为止只为 !text/ 插件实现了转换。 我们的团队完全脱离了 requirejs,所以我没有理由继续沿着这条路走下去。

我同意,我认为使用 RequireJS 编写代码没有什么价值。 将 CommonJS/ES2015 模块代码编译为 requirejs 用于生产对我来说是有意义的,但手动编写这种风格的代码似乎并不好。

我刚刚从 RequireJS 迁移到 webpack。 我们的代码库中有 300 多个组件。 整个过程出奇地简单无痛。

我使用的工具是https://github.com/Skookum/recast-to-cjs,用于将代码从 AMD 转换为 CommonJS 样式。

同样在https://github.com/facebook/jscodeshift的帮助下,我们在几天内将我们的代码库从 React 0.11 迁移到了 0.14。

希望这可以帮助处于相同情况的人。

@tendant不错! 这正是我之前所说的 :) 很高兴它对你很有效。

既然关闭了,这是否意味着 Facebook 不会增加对此的支持?

如果您指的是 Facebook,那么是的,不太可能有“官方”支持。 这不应该阻止您为 Jest 做出贡献并获得此功能,但我相信现在大多数人已经转向 ES 模块或 CommonJS。

是的,我知道。 不幸的是,我无法摆脱这些依赖关系,因为它是为了工作。

babel-plugin-transform-amd-to-commonjs可以证明对解决 Jest+AMD 的问题很有用,特别是如果你已经在使用类似 babel-jest 的东西。

我已经建立了一个示例项目,它展示了如何通过在测试环境中运行转换来让 Jest 透明地需要 AMD 文件。

我不确定这种方法在实际项目中的细节——尤其是在 Jest/RequireJS/Webpack/etc 之间进行配置共享的好方法。 对 .js 配置文件的 Jest 支持将是朝着更可重用的解决方案迈出的一步(请参阅 https://github.com/facebook/jest/issues/2140)。

@msrose这太棒了。 非常感谢你分享这个。

我明白这是一个老问题。 一个简单的转换可以工作:

exports.process = function (content) {
  return 'function define(name, deps, body) { module.exports = body.apply(undefined, deps.map(require)); }' + content;
}

我认为 AMD -> CJS 的转换可以通过多种方式完成,例如deamdify 、注入包装器等。问题仍然没有解决,是 Require 样式的加载器/插件语法。 这就是fooTemplate = require('tpl!foo.tpl')barJson = require('json!bar.json') (作为相对常见的东西)。 但是有很多这样的和现实世界的require-js项目都充斥着这种语法。

如果有一种简单的方法可以直接重用转换系统中现有的require-js插件,最终馈入jest | 的模块加载器,那就太好了。

+1

ReferenceError: define is not defined

+1

失败 srcApp.test.js
● 测试套件无法运行

ReferenceError: define is not defined

您应该使用 umd 而不是 amd。 如果这不可行,您应该添加一个转换(例如上面链接的 babel 插件)。

当涉及到loader!语法时,我们不会支持它(我们也不支持 Webpack)。 解决方法是转换导入(删除加载器)并让 Jest 使用其transform配置进行转换。 相关讨论:#4868

此页面是否有帮助?
0 / 5 - 0 等级