我在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之间有什么区别,为什么在这里使用它们。
当前回答
exports和module.exports是相同的,除非在模块内重新分配导出。
考虑这一点最简单的方法是认为这一行隐式地位于每个模块的顶部。
var exports = module.exports = {};
如果在模块内重新分配导出,则在模块内将其重新分配,并且不再等于module.exports。这就是为什么,如果要导出函数,必须执行以下操作:
module.exports = function() { ... }
如果只将函数(){…}分配给导出,则将导出重新分配为不再指向module.exports。
如果您不想每次通过module.exports引用函数,可以执行以下操作:
module.exports = exports = function() { ... }
注意,module.exports是最左边的参数。
将财产附加到导出不一样,因为您不需要重新分配它。这就是为什么可以这样做的原因
exports.foo = function() { ... }
其他回答
这是曼宁出版的动作书中关于node.js中节点模块的一个很好的描述。最终在应用程序中导出的是module.exports.exportsup简单地作为module.exports的全局引用,它最初定义为可以向其中添加财产的空对象。所以exports.myFunc只是一种速记对于module.exports.myFunc。因此,如果将导出设置为其他值,则会断开引用模块导出和导出。因为module.exports是真正的导出,导出将不再按预期工作,它不引用模块.不再导出。如果要维护该链接,可以创建module.exports再次引用导出如下:
module.exports = exports = db;
我发现这个链接对回答上述问题很有用。
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应该可以
设置module.exports允许在需要时像调用函数一样调用database_module函数。简单地设置导出不允许函数导出,因为node导出对象模块。导出引用。以下代码不允许用户调用函数。
模块.js
以下操作不起作用。
exports = nano = function database_module(cfg) {return;}
如果设置了module.exports,则以下操作将起作用。
module.exports = exports = nano = function database_module(cfg) {return;}
安慰
var func = require('./module.js');
// the following line will **work** with module.exports
func();
基本上,node.js不导出导出当前引用的对象,而是导出导出最初引用的对象的财产。虽然Node.js确实导出了对象module.exports引用,但允许您像函数一样调用它。
第二个最不重要的原因
他们设置了module.exports和exports,以确保导出不引用先前导出的对象。通过设置这两个选项,您可以使用导出作为速记,并避免以后可能出现的错误。
使用exports.rop=true而不是module.exports.rop=true可以保存字符并避免混淆。
我通过了一些测试,我认为这可能会对这个问题有所启发。。。
应用.js:
var ...
, routes = require('./routes')
...;
...
console.log('@routes', routes);
...
/routes/index.js的版本:
exports = function fn(){}; // outputs "@routes {}"
exports.fn = function fn(){}; // outputs "@routes { fn: [Function: fn] }"
module.exports = function fn(){}; // outputs "@routes function fn(){}"
module.exports.fn = function fn(){}; // outputs "@routes { fn: [Function: fn] }"
我甚至添加了新文件:
./routes/index.js:
module.exports = require('./not-index.js');
module.exports = require('./user.js');
./routes/not-index.js:
exports = function fn(){};
./routes/user.js:
exports = function user(){};
我们得到输出“@routes{}”
./routes/index.js:
module.exports.fn = require('./not-index.js');
module.exports.user = require('./user.js');
./routes/not-index.js:
exports = function fn(){};
./routes/user.js:
exports = function user(){};
我们得到输出“@routes{fn:{},user:{}}”
./routes/index.js:
module.exports.fn = require('./not-index.js');
module.exports.user = require('./user.js');
./routes/not-index.js:
exports.fn = function fn(){};
./routes/user.js:
exports.user = function user(){};
我们得到输出“@routes{user:[Function:user]}”如果我们将user.js更改为{ThisLoadedLast:[Function:ThisLoadedLast]},我们将得到输出“@routes{ThisLoadedLast:[Function:TThisLoadedlast]}”。
但如果我们修改/routes/index.js。。。
./routes/index.js:
module.exports.fn = require('./not-index.js');
module.exports.ThisLoadedLast = require('./user.js');
./routes/not-index.js:
exports.fn = function fn(){};
./routes/user.js:
exports.ThisLoadedLast = function ThisLoadedLast(){};
…我们得到“@routes{fn:{fn:[Function:fn]},ThisLoadedLast:{ThisLoadedLast:[Function:ThisLoadedLast]}}”
所以我建议在模块定义中始终使用module.exports。
我不完全理解Node内部的情况,但如果您能理解这一点,请发表评论,因为我相信这会有所帮助。
--快乐的编码
这显示了require()如何以最简单的形式工作,摘自Eloquent JavaScript
问题模块不可能直接导出导出对象以外的值,例如函数。例如,模块可能只希望导出其定义的对象类型的构造函数。现在,它无法做到这一点,因为require始终使用它创建的导出对象作为导出值。
解决方案为模块提供另一个变量module,它是一个具有属性导出的对象。此属性最初指向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);