导入自动调用函数将此绑定到window对象

时间:2018-04-05 07:45:24

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

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

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

这有助于使用反应组件内的翻译。例如,使用全局定义的函数.jsx

在我们的gettext()文件中包含翻译字符串
<p>{ gettext('got it') }</p>

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

import './djangojs';

但是jest报告错误

TypeError: Cannot read property 'django' of undefined

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

2 个答案:

答案 0 :(得分:0)

解决方案:

我已使用setupFiles直接导入django javascript模块,因为@dfsq告诉

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

答案 1 :(得分:0)

问题是巴别特有的。 Babel通常用于Jest测试装置,它可能在这里使用。

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

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

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

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

预计script不必被编译(它将按原样评估)并且不依赖于上下文(不会使用{ {1}},因为它在全局范围内不可用)。即require适用于eval等常规脚本,但不适用于CommonJS模块。

如果模块不应全局可用或在测试之间有所不同,这可能很有用。

如果它应该可用于所有测试,则应使用./djangojs,如另一个答案所示。