全局变量在NodeJS中不起作用

时间:2017-01-05 15:41:09

标签: javascript node.js laravel-elixir rollupjs

我试图让全局变量在node.js中运行,但似乎我并不真正理解这个概念,即使我的理解与文档相符。

最小例子

我的 main.js 文件是使用汇总编译的:

global.a = 1;
require('./core/test.js');

我的 core / test.js 文件只是:

console.log(a);

这会导致错误:

  

未捕获的ReferenceError:a未定义

完全编译的输出是:

(function (exports) {
'use strict';

var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};

console.log(a);

commonjsGlobal.a = 1;

}((this.LaravelElixirBundle = this.LaravelElixirBundle || {})));
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjpudWxsLCJzb3VyY2VzIjpbIkM6L3dhbXAvd3d3L3V1YmMvcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb3JlL3Rlc3QuanMiLCJDOi93YW1wL3d3dy91dWJjL3Jlc291cmNlcy9hc3NldHMvanMvYXBwLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImNvbnNvbGUubG9nKGEpO1xyXG4iLCJnbG9iYWwuYSA9IDE7XHJcbnJlcXVpcmUoJy4vY29yZS90ZXN0LmpzJyk7XHJcbiJdLCJuYW1lcyI6WyJnbG9iYWwiXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQzs7QUNBZkEsY0FBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7OyJ9

似乎aconsole.log(a);之后定义了。我不能100%确定这在JS中是否重要,但可能导致错误。

所以我的问题是:是什么导致了这一点,我在这里做错了什么?

可能相关的信息:我使用Laravel Elixir编译所有内容。

注意:请不要在node.js或一般情况下讨论是否使用全局变量。我知道这通常是一个坏主意,但在这种情况下我有充分的理由这样做。

编辑:附加上下文

我真正想做的是让Zurb基金会通过node.js与Laravel Elixir合作。我通过NPM安装了foundation-sitesfoundation-sites依赖于jquery,它本身就是自带的。 然而,基金会似乎没有遵循通常在其自己的js文件中使用var jquery = require('jquery');之类的惯例。它实际上依赖于可用的全局jQuery变量。因此,我必须以某种方式确保。

我的实际文件如下:

global.jQuery = global.$ = require('jquery');
require('foundation-sites');

因此,如果有任何基金会/ Laravel特定的通道,我也很乐意听到它们。有没有我没有得到的东西,或者基金会没有创造他们的包装"对"方式是什么?

4 个答案:

答案 0 :(得分:2)

你说得对,它是正确的。这是一个有效的例子:

// file1.js
global.a = 'hello';
require('./file2');

// file2.js
console.log(a);

运行node file1.js,您会看到'hello'已打印到控制台。

看起来你已经使用了其他工具(Laravel / Elixir)。直接使用节点,看看会发生什么。

答案 1 :(得分:1)

在我看来,你的捆绑商不会尊重你正在做这两行的订单。你的来源显然是:

global.a = 1;
require('./core/test.js');

...但捆绑的结果显然是相反的:

console.log(a);
commonjsGlobal.a = 1;

似乎正在提升require次来电。通常,需要在执行控制流中的特定点执行require调用不是最佳实践(事实上,在为ES2015定义模块时,import被明确定义为未执行在模块的逐步控制流程中。

因此,如果您需要这样做,您可能想要查看另一个捆绑器。但请检查它是否支持依赖解析顺序以外的顺序。

答案 2 :(得分:0)

好吧,我使用browserify代替rollup以非常简单的方式解决了这个问题。感谢其他答案指出我正确的方向。这不是一个完美的解决方案,我仍然不完全理解两者之间的差异,但它会为这个项目做。

我的gulpfile的相关部分:

mix.browserify('app.js','public/js/app.js');

要在Laravel Elixir中使用browserify,我使用了

npm install laravel-elixir-browserify-official --save-dev

答案 3 :(得分:0)

我通过提供设置所需变量的output.intro解决了汇总的问题。在您的情况下,这将是:

// rollup.config.js
export default {
  // ...
  output: {
    // ...
    intro: `let a = 1;`
  }
};

诚然,这可以算作是骇客,但在我的情况下解决了捆绑问题(不选择不使用汇总)。