我在Node.js模块中找到了以下合同:
module.exports = exports = nano = function database_module(cfg) {...}
我不知道什么之间的不同module.exports
和exports
为什么都被用在这里。
我在Node.js模块中找到了以下合同:
module.exports = exports = nano = function database_module(cfg) {...}
我不知道什么之间的不同module.exports
和exports
为什么都被用在这里。
1.exports->用作单例实用程序
2. module- exports-> 用作逻辑对象,如service,model等
“如果您希望模块导出的根是一个函数(例如构造函数),或者想一次导出一个完整的对象而不是一次构建一个属性,则将其分配给module.exports而不是出口。” - http://nodejs.org/api/modules.html
这展示了如何require()
以最简单的形式工作(摘自Eloquent JavaScript)
问题
模块无法直接导出导出对象以外的值,例如函数。例如,一个模块可能只想导出其定义的对象类型的构造函数。目前,它无法执行此操作,因为require始终将exports
其创建的对象用作导出值。
解决方案
为模块提供另一个变量,module
该变量是具有属性的对象exports
。此属性最初指向由require创建的空对象,但可以用另一个值覆盖以导出其他内容。
function require(name) {
if (name in require.cache)
return require.cache[name];
var code = new Function("exports, module", readFile(name));
var exports = {}, module = {exports: exports};
code(exports, module);
require.cache[name] = module.exports;
return module.exports;
}
require.cache = Object.create(null);
来自文档
导出变量在模块的文件级范围内可用,并在评估模块之前为其指定了module.exports的值。
它允许使用快捷方式,以便module.exports.f = ...可以更简洁地编写为exports.f =...。但是,请注意,与任何变量一样,如果将新值分配给exports,不再绑定到module.exports:
它只是指向module.exports的变量。
我发现此链接对于回答上述问题很有用。
http://timnew.me/blog/2012/04/20/exports-vs-module-exports-in-node-js/
添加到其他帖子节点中的模块系统执行
var exports = module.exports
在执行代码之前。因此,当您要exports = foo时,可能要执行module.exports = exports = foo,但使用exports.foo = foo应该没问题。
这是结果
console.log("module:");
console.log(module);
console.log("exports:");
console.log(exports);
console.log("module.exports:");
console.log(module.exports);
也:
if(module.exports === exports){
console.log("YES");
}else{
console.log("NO");
}
//YES
注意:CommonJS规范仅允许使用exports变量来公开公共成员。因此,命名的导出模式是唯一与CommonJS规范真正兼容的模式。module.exports的使用是Node.js提供的扩展,以支持更广泛的模块定义模式。
这是Manning出版的操作手册中有关node.js中的节点模块的良好描述。
最终在您的应用程序中导出的是module.exports。可以将exports设置为对module.exports的全局引用,该模块最初定义为可以向其添加属性的空对象。所以exports.myFunc是刚刚速记module.exports.myFunc。
其结果是,如果出口被设置为别的,它打破了基准之间
module.exports和出口。因为module.exports
是真正要导出的内容,导出将不再按预期方式工作-它不再引用.exports模块。如果要维护该链接,可以使module.exports再次
引用导出,如下所示:
module.exports = exports = db;
在JavaScript中通过引用传递对象的方式有微妙的区别。
exports
和module.exports
都指向同一个对象。exports
是变量,module.exports
是模块对象的属性。
说我写这样的东西:
exports = {a:1};
module.exports = {b:12};
exports
而module.exports
现在指向不同的对象。修改导出不再修改module.exports。
导入功能检查module.exports
时得到{b:12}
最初,module.exports=exports
和require
函数会返回所module.exports
引用的对象。
如果我们向对象添加属性,例如exports.a=1
,则module.exports和export 仍引用同一对象。因此,如果我们调用require并将模块分配给变量,则该变量具有a属性,其值为1;
但是,如果我们覆盖其中的一个,例如,exports=function(){}
则它们现在有所不同:export指向一个新对象,而module.exports指向原始对象。如果我们需要该文件,它将不会返回新对象,因为module.exports没有引用新对象。
对我而言,我将继续添加新属性,或将它们都覆盖到新对象中。仅仅覆盖一个是不对的。并记住那module.exports
才是真正的老板。
exports
并且module.exports
是相同的,除非你重新分配exports
你的模块中。
考虑这一点的最简单方法是认为此行隐式位于每个模块的顶部。
var exports = module.exports = {};
如果您在模块中重新分配exports
,则在模块中重新分配它,而不再等于module.exports
。这就是为什么如果要导出功能,必须执行以下操作的原因:
module.exports = function() { ... }
如果您只是将您的分配function() { ... }
给exports
,那么您将被重新分配exports
以不再指向module.exports
。
如果不想module.exports
每次都引用函数,可以执行以下操作:
module.exports = exports = function() { ... }
注意,这module.exports
是最左边的参数。
exports
由于没有重新分配属性,因此将属性附加到的属性是不同的。这就是为什么这样
exports.foo = function() { ... }
module.exports
exports
在评估模块之前,它们都指向同一对象。module.exports
当您的模块在另一个模块中使用usingrequire
语句使用时,添加到对象的任何属性都将可用。exports
是可用于同一事物的快捷方式。例如:相当于写:
因此,只要您不为
exports
变量分配新值就可以。当您执行以下操作时:由于您正在为其分配新值,
exports
因此不再引用导出的对象,因此将保留在模块本地。如果您打算为分配一个新值,
module.exports
而不是向可用的初始对象添加新属性,则可能应该考虑执行以下操作:Node.js网站对此有很好的解释。