全局变量在 NodeJS 中不起作用
Global variable not working in NodeJS
我试图让全局变量在 node.js 中工作,但我似乎并不真正理解这个概念,尽管我的理解与文档相符。
最小示例
我的main.js文件,使用rollup编译的是:
global.a = 1;
require('./core/test.js');
我的 core/test.js 文件很简单:
console.log(a);
这会导致错误:
Uncaught ReferenceError: a is not defined
完全编译后的输出是:
(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
似乎 a
在 console.log(a);
之后定义了 。我不是 100% 确定这在 JS 中是否重要,但它可能会导致错误。
所以我的问题是:是什么原因造成的,我做错了什么?
可能的相关信息:我正在使用 Laravel Elixir 来编译所有内容。
注意:请不要post讨论是否在node.js或一般情况下使用全局变量。我知道这通常是个坏主意,但在这种情况下我有充分的理由这样做。
编辑:附加上下文
我真正想做的是通过 node.js 让 Zurb Foundation 与 Laravel Elixir 一起工作。我通过 NPM 安装了 foundation-sites
。 foundation-sites
依赖于 jquery
,它自己拉动。 但是,Foundation 似乎并没有遵循在其自己的 js 文件中仅使用 var jquery = require('jquery');
之类的常规约定。它实际上依赖于可用的全局 jQuery
变量。因此我必须以某种方式确保这一点。
我的实际文件如下所示:
global.jQuery = global.$ = require('jquery');
require('foundation-sites');
因此,如果有任何 Foundation/Laravel-specific 答案,我也很乐意听到。有没有我没有得到的东西,或者 Foundation 只是没有以 "right" 的方式创建他们的包?
你是对的,它应该有效。这是一个工作示例:
// file1.js
global.a = 'hello';
require('./file2');
// file2.js
console.log(a);
运行 node file1.js
,你会看到 'hello'
打印到控制台。
您似乎使用了其他工具 (Laravel / Elixir)。直接使用node,看看会发生什么。
在我看来,您的捆绑器存在问题,不遵守您执行这两行的顺序。您的来源显然是:
global.a = 1;
require('./core/test.js');
...但捆绑的结果显然是相反的:
console.log(a);
commonjsGlobal.a = 1;
它似乎正在挂起 require
电话。通常,在执行控制流中的特定点进行 require
调用并不是最佳实践(事实上,在为 ES2015 定义模块时,import
被明确定义为未执行在模块的逐步控制流程中)。
因此,如果您需要这样做,您可能需要查看另一个捆绑器。但是检查它是否支持依赖解析顺序以外的顺序。
好吧,我通过使用 browserify
而不是 rollup
以一种非常简单的方式解决了这个问题。感谢其他答案为我指明了正确的方向。这不是一个完美的解决方案,我仍然不完全理解两者之间的区别,但它对这个项目有用。
我的 gulpfile 的相关部分:
mix.browserify('app.js','public/js/app.js');
要将 browserify
与 Laravel Elixir 一起使用,我使用了
npm install laravel-elixir-browserify-official --save-dev
我通过提供设置所需变量的 output.intro
为 rollup 解决了这个问题。在您的情况下,这将是:
// rollup.config.js
export default {
// ...
output: {
// ...
intro: `let a = 1;`
}
};
诚然,这可以算作黑客攻击,但在我的案例中解决了捆绑问题(从汇总切换不是一个选项)。
我试图让全局变量在 node.js 中工作,但我似乎并不真正理解这个概念,尽管我的理解与文档相符。
最小示例
我的main.js文件,使用rollup编译的是:
global.a = 1;
require('./core/test.js');
我的 core/test.js 文件很简单:
console.log(a);
这会导致错误:
Uncaught ReferenceError: a is not defined
完全编译后的输出是:
(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
似乎 a
在 console.log(a);
之后定义了 。我不是 100% 确定这在 JS 中是否重要,但它可能会导致错误。
所以我的问题是:是什么原因造成的,我做错了什么?
可能的相关信息:我正在使用 Laravel Elixir 来编译所有内容。
注意:请不要post讨论是否在node.js或一般情况下使用全局变量。我知道这通常是个坏主意,但在这种情况下我有充分的理由这样做。
编辑:附加上下文
我真正想做的是通过 node.js 让 Zurb Foundation 与 Laravel Elixir 一起工作。我通过 NPM 安装了 foundation-sites
。 foundation-sites
依赖于 jquery
,它自己拉动。 但是,Foundation 似乎并没有遵循在其自己的 js 文件中仅使用 var jquery = require('jquery');
之类的常规约定。它实际上依赖于可用的全局 jQuery
变量。因此我必须以某种方式确保这一点。
我的实际文件如下所示:
global.jQuery = global.$ = require('jquery');
require('foundation-sites');
因此,如果有任何 Foundation/Laravel-specific 答案,我也很乐意听到。有没有我没有得到的东西,或者 Foundation 只是没有以 "right" 的方式创建他们的包?
你是对的,它应该有效。这是一个工作示例:
// file1.js
global.a = 'hello';
require('./file2');
// file2.js
console.log(a);
运行 node file1.js
,你会看到 'hello'
打印到控制台。
您似乎使用了其他工具 (Laravel / Elixir)。直接使用node,看看会发生什么。
在我看来,您的捆绑器存在问题,不遵守您执行这两行的顺序。您的来源显然是:
global.a = 1;
require('./core/test.js');
...但捆绑的结果显然是相反的:
console.log(a);
commonjsGlobal.a = 1;
它似乎正在挂起 require
电话。通常,在执行控制流中的特定点进行 require
调用并不是最佳实践(事实上,在为 ES2015 定义模块时,import
被明确定义为未执行在模块的逐步控制流程中)。
因此,如果您需要这样做,您可能需要查看另一个捆绑器。但是检查它是否支持依赖解析顺序以外的顺序。
好吧,我通过使用 browserify
而不是 rollup
以一种非常简单的方式解决了这个问题。感谢其他答案为我指明了正确的方向。这不是一个完美的解决方案,我仍然不完全理解两者之间的区别,但它对这个项目有用。
我的 gulpfile 的相关部分:
mix.browserify('app.js','public/js/app.js');
要将 browserify
与 Laravel Elixir 一起使用,我使用了
npm install laravel-elixir-browserify-official --save-dev
我通过提供设置所需变量的 output.intro
为 rollup 解决了这个问题。在您的情况下,这将是:
// rollup.config.js
export default {
// ...
output: {
// ...
intro: `let a = 1;`
}
};
诚然,这可以算作黑客攻击,但在我的案例中解决了捆绑问题(从汇总切换不是一个选项)。