我在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:{}的属性,默认情况下该属性为空对象。
您可以创建函数/中间件并将其添加到这个空的导出对象中,例如exports.findById()=>{…},然后在应用程序中的任何位置使用。。。
控制器/user.js
exports.findById = () => {
// do something
}
需要在routes.js中使用:
const {findyId} = './controllers/user'
其他回答
从文档中
exports变量在模块的文件级范围内可用,并在评估模块之前为其赋值module.exports。它允许快捷方式,因此module.exports.f=。。。可以更简洁地写成exports。f=。。。。但是,请注意,与任何变量一样,如果为导出分配了新值,则不再将其绑定到module.exports:
它只是一个指向module.exports的变量。
设置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可以保存字符并避免混淆。
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() { ... }
为什么这两个都用在这里
我相信他们只是想清楚module.exports、exports和nano指向同一个函数——允许您使用任意一个变量来调用文件中的函数。nano为函数的功能提供了一些上下文。
导出不会被导出(只有module.exports会被导出),那么为什么还要麻烦覆盖它呢?
冗长的权衡限制了未来错误的风险,例如在文件中使用导出而不是module.exports。它还澄清了module.exports和exports实际上指向相同的值。
module.exports与导出
只要不重新分配module.exports或exports(而是向它们都引用的对象添加值),就不会有任何问题,并且可以安全地使用exports以更简洁。
当将其中一个分配给非对象时,它们现在指向不同的位置,这可能会令人困惑,除非您有意希望module.exports是特定的(例如函数)。
将导出设置为非对象没有多大意义,因为必须在末尾设置module.exports=导出,才能在其他文件中使用它。
let module = { exports: {} };
let exports = module.exports;
exports.msg = 'hi';
console.log(module.exports === exports); // true
exports = 'yo';
console.log(module.exports === exports); // false
exports = module.exports;
console.log(module.exports === exports); // true
module.exports = 'hello';
console.log(module.exports === exports); // false
module.exports = exports;
console.log(module.exports === exports); // true
为什么将module.exports分配给函数?
更简洁!比较第二个示例的长度:
helloWorld1.js:module.exports.hello = () => console.log('hello world');
app1.js:let sayHello=require('./helloWorld1');sayHellohello;//你好,世界
helloWorld2.js:module.exports = () => console.log('hello world');
app2.js:let sayHello=require('./helloWorld2');说你好;//你好,世界
module.export和exports都指向同一个对象,然后对模块求值。
使用require语句在另一个模块中使用模块时,添加到module.exports对象的任何属性都将可用。导出是一种快捷方式,可用于相同的事情。例如:
module.exports.add = (a, b) => a+b
相当于写:
exports.add = (a, b) => a+b
因此,只要不为导出变量分配新值,就可以了。当你这样做时:
exports = (a, b) => a+b
当您为导出分配新值时,它不再引用导出的对象,因此将保持模块的本地状态。
如果您计划为module.exports分配一个新值,而不是向可用的初始对象添加新的财产,您可能应该考虑如下所示:
module.exports = exports = (a, b) => a+b
Node.js网站对此有很好的解释。