node.js标准模块的全局变量?

时间:2010-11-10 02:14:01

标签: javascript module node.js global-variables shared-libraries

我知道全局变量很糟糕。

但是如果我在我的框架中的40个文件中使用node的模块“util”,那么将它声明为全局变量并不是更好:

util = require('util');
在index.js文件中

而不是在40个文件中写入该行?

因为我经常在每个文件中使用相同的5-10个模块,这样可以节省大量时间,而不是一直复制粘贴。

在这种情况下,DRY不是很好吗?

6 个答案:

答案 0 :(得分:102)

你可以有一个共同的模块。

common.js:

Common = {
  util: require('util'),
  fs:   require('fs'),
  path: require('path')
};

module.exports = Common;

app.js:

var Common = require('./common.js');
console.log(Common.util.inspect(Common));

答案 1 :(得分:43)

每个模块应该是独立的。在每个模块的第一个之后,要求不会花费任何费用。

如果您想单独测试一个模块怎么办?您会遇到很多问题,因为它无法识别您的应用中的某些“全局”要求。

是的,即使在这种情况下,全局变量也很糟糕。 Globals几乎总是毁了:可测试性,封装性和易维护性。

更新的答案2012年1月

global对象现在是每个模块中的全局对象。因此,每次在模块内部分配全局变量(无范围)时,它都会成为该模块的global对象的一部分。

因此global对象仍然不是全局,并且不能这样使用。

2012年12月更新

global对象现在具有应用程序中的全局范围,可用于存储需要从所有模块访问的任何数据/函数。

答案 2 :(得分:25)

global.util = require('util');

node documentation中有关于全局对象的部分。

但是,应谨慎使用全局变量。通过向全局空间添加模块,可以降低可测试性和封装性。但是有些情况下使用这种方法是可以接受的。例如,我将函数和对象添加到全局命名空间以在我的单元测试脚本中使用。

答案 3 :(得分:20)

我对这个帖子中的答案感到困惑。

我能够做到这一点......

文件:test.js

global.mytest = {
    x: 3,
    y: function() { console.log('Works.'); }
};

文件:test2.js

console.log('Does this work?');
mytest.y();

文件:server.js

require('test.js');
require('test2.js');

它似乎可以解决所需的问题。第一个要求将mytest对象放入全局范围,然后第二个要求可以访问该对象而不需要任何其他限定符。

我试图解决这个问题(这使我从Google搜索中找到了这个帖子),我想发布一些似乎对我有用的内容。也许自最初答案以来情况发生了变化。

答案 4 :(得分:0)

我已成功使用process对象传递配置对象。虽然在理论上遇到了与上面提到的完全相同的问题(封装,可测试性等),但是当仅使用非状态修改属性(基本上具有基元的哈希表)时,它可以正常工作。

答案 5 :(得分:-3)

如果你将模块包装在块中(例如anon函数),你可以绑定到本地名称(通过参数或'var'),然后你想要任意长(可能是“包”标签)名称(如果你连此时需要全球化。)

例如,我的模块通常类似于:

;(function ($, $exp, other) {
  $(...)
  other.xyz()
  $exp.MyExportedObject = ...;
})(jQuery, window, some_module.other_expression) // end module

我使用jQuery和noConflict,这是前者,后者表明你可以为任何表达式做这个 - 全局,需求,计算,内联,无论什么......这同样的“包装”方法可以用来消除所有(或几乎所有)“特殊命名”全局变量 - 全局变量必须存在于某个层次,但是,消除潜在冲突是一个非常大的胜利。