【问题标题】:import auto invoking function binding this to window object导入将 this 绑定到窗口对象的自动调用函数
【发布时间】:2018-09-14 22:49:18
【问题描述】:

在一个笑话测试中,我需要导入一个声明一些全局函数的 javascript 模块。这个 javascript 模块是从 django (ex jsi18n) 自动生成的,它是一个自动调用函数

(function(globals) {
    var django = globals.django || (globals.django = {});
    ...
}(this));

这有助于在 react 组件中使用翻译。例如,使用全局定义函数 gettext() 在我们的 .jsx 文件中包含翻译字符串

<p>{ gettext('got it') }</p>

我尝试使用标准格式导入模块

import './djangojs';

不过开玩笑的​​报错

TypeError: Cannot read property 'django' of undefined

因为this 它是未定义的(严格模式)。所以我尝试手动编辑模块并在末尾添加}(this || window)); 并正常工作。 但是该模块每次都是自动生成的。那么如何在不手动编辑文件的情况下将this 绑定到window 以使用全局对象呢?

【问题讨论】:

  • 向维护 Django 的人提交错误。他们的代码生成器很讨厌。他们为什么不使用 UMD?
  • 你可以模拟整个./djangojs
  • 如何模拟它? @dfsq
  • 使用jest.mock
  • @dfsq 它不起作用,因为 this 仍未定义

标签: javascript node.js ecmascript-6 babeljs jestjs


【解决方案1】:

解决方案:

正如@dfsq 所说,我已经使用setupFiles 直接导入了django javascript 模块

"setupFiles": [
    "<rootDir>/path/to/jsi18n/djangojs.js",
    "<rootDir>/path/to/js/reverse.js"
],

【讨论】:

    【解决方案2】:

    这个问题是 Babel 特有的。 Babel 常用于 Jest 测试台,很可能在这里使用。

    Babel transform-es2015-modules-commonjs 为 ES 模块导入和 require 启用严格模式,因此 this 在导入模块中是 undefined

    为了让一段代码在其上下文处于严格模式时以松散模式执行,它应该在全局上下文中进行评估:

    const fs = require('fs');
    const script = fs.readFileSync(require.resolve('./djangojs')).toString();
    new Function(script)(); // or (0, eval)(script);
    

    而不是import './djangojs'require('./djangojs')

    预计script 不必被转译(它将按原样评估)并且不依赖于上下文(不使用require,因为它在全局上下文中不可用)。 IE。 eval 将适用于像 ./djangojs 这样的常规脚本,但不适用于 CommonJS 模块。

    如果模块不应该在全局范围内可用或可能因测试而异,这可能很有用。

    如果它应该可用于所有测试,那么应该使用 setupFiles,正如另一个答案所暗示的那样。

    【讨论】:

      猜你喜欢
      • 2012-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-02
      • 2011-09-20
      • 1970-01-01
      • 2011-12-20
      • 2017-12-05
      相关资源
      最近更新 更多