【问题标题】:Can I inject globals into a Node module before it's loaded?我可以在加载之前将全局变量注入 Node 模块吗?
【发布时间】:2012-06-07 06:23:03
【问题描述】:

我正在编写一个用于浏览器的应用程序,并且我想为我的库代码编写自动化测试。我想在浏览器之外,在像Node 这样的命令行环境中运行这些测试。我还没有选择一个测试框架,虽然我倾向于像 MochaJasmine 这样的 BDD 框架。

我的代码依赖于Knockout 的可观察属性。不幸的是,Knockout 库不仅包含可观察的属性,还包含将它们绑定到 DOM 的代码。因此,如果我只是尝试从 Node 中 require() Knockout 库,我会收到错误,因为该库正在尝试引用 Node 中未定义的 windownavigatordocument 变量。 Knockout 实际上并没有使用任何这些变量很多——它主要是对 DOM 绑定的一点特征检测,这对我来说并不重要——但因为它确实使用了它们,所以 Node甚至不会加载文件。

所以这是我的问题:我可以在模块加载时将虚拟变量注入到模块中吗?我可以说“在你加载源文件之后,但在你开始运行之前它,让我在模块内部设置一些变量,以便代码能够成功运行”?

我知道CoffeeScript 已经修补了Node 的模块加载器,因此它可以加载.coffee 文件以及.js;因此,如果我只知道如何,似乎也有一些方法可以修补它以注入变量。

【问题讨论】:

    标签: unit-testing node.js knockout.js


    【解决方案1】:

    是的,是的,你可以——创建它们然后使用它们,全局变量没有隔离。

    或者,您可能希望以文本形式将 shim 包裹在代码周围,将它们提供在闭包中。 jsdom 做这样的事情来运行 jQuery。 (而且它为此提供了一个真正的 DOM!)

    【讨论】:

    • 天啊!你是对的,在 JavaScript 中,我可以在 Knockout 上调用 require() 之前执行 window={}; 之类的操作。但是我使用的是 CoffeeScript,它默认将所有内容包装在一个匿名函数中,因此全局变量不会在所有内容中流血,所以我必须设置 global.window。一旦我知道有东西要找,就不难找到了——感谢你为我指明了正确的方向。 (感谢您指出 jsdom ——这也可能对我有所帮助!)
    【解决方案2】:

    Node.js 不是常用意义上的“无头”环境(无头浏览器)。

    jsdom 可以带你走得更远,但你应该研究一下PhantomJS,它是无头 webkit,包含 DOM 和所有内容,应该非常适合你的用例。

    【讨论】:

    • 我看过一点 PhantomJS,但它的测试运行器支持似乎很笨拙(DOM 抓取),而且由于测试由 <script> 标记引用,因此在 CoffeeScript 中编写测试没有什么好方法。所以我想深入研究 Node,看看它是如何堆积起来的。
    • 感谢您对术语的更正。我已经编辑了我的帖子以删除“无头”一词,因为它并不意味着我认为的那样。
    • coffeescript 在 Phantom 中使用 <script type="text/coffeescript"> 方法运行良好,您也可以在运行前编译文件。你对 DOM 抓取是什么意思?就像在浏览器上运行测试套件一样
    • 您已将 <script type="text/coffeescript"> 与外部脚本 (<script src="...") 一起使用? CoffeeScript 站点似乎很清楚它仅适用于内联脚本。关于你关于 DOM 抓取的问题,Phantom 的 Jasmine runner (examples/run-jasmine.js) 反复轮询 DOM 元素,直到它看到其中一个出现测试结果,然后它必须遍历 DOM 以显示测试结果到控制台。
    【解决方案3】:

    也许使用 felixge 的节点 sandboxed-module,您可以沙盒淘汰库并将全局变量注入沙盒模块。

    来自自述文件:

    var SandboxedModule = require('sandboxed-module');
    var user = SandboxedModule.require('./user', {
      requires: {'mysql': {fake: 'mysql module'}},
      globals: {myGlobal: 'variable'},
      locals: {myLocal: 'other variable'},
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-27
      • 2012-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-09
      • 2014-09-11
      相关资源
      最近更新 更多