一尘不染

Node.js 中的 module.exports 与导出

Node.js

我在 Node.js 模块中找到了以下合同:

module.exports = exports = nano = function database_module(cfg) {...}

我想知道两者之间有什么区别module.exports以及exports为什么在这里使用两者。


阅读 136

收藏
2022-04-14

共2个答案

一尘不染

设置module.exports允许database_module函数在 时像函数一样被调用required。简单exports的设置不允许函数被导出,因为节点导出了对象module.exports引用。以下代码不允许用户调用该函数。

module.js

以下将不起作用。

exports = nano = function database_module(cfg) {return;}

module.exports如果设置,以下将起作用。

module.exports = exports = nano = function database_module(cfg) {return;}

*console*

var func = require('./module.js');
// the following line will **work** with module.exports
func();

基本上node.js不会导出exports当前引用的对象,而是导出exports最初引用的对象的属性。尽管Node.js确实导出了对象module.exports引用,但允许您像调用函数一样调用它。


第二个最不重要的原因

他们同时设置module.exportsexports确保exports不引用先前导出的对象。通过将两者都设置exports为速记,并避免以后出现潜在的错误。

使用exports.prop = true 而不是module.exports.prop = true保存字符并避免混淆。

2022-04-14
一尘不染

您可以想象在文件的开头有类似的内容(仅用于解释):

var module = new Module(...);
var exports = module.exports;

在此处输入图像描述

因此,无论您做什么,请记住,当您从其他地方需要该模块时,将从您的模块返回module.exportsNOT 。exports

因此,当您执行以下操作时:

exports.a = function() {
    console.log("a");
}
exports.b = function() {
    console.log("b");
}

您正在添加 2 个函数ab指向的对象module.exports,因此typeof返回结果将是object{ a: [Function], b: [Function] }

当然,如果您module.exports在本例中使用而不是exports.

在这种情况下,您希望您module.exports的行为类似于导出值的容器。然而,如果您只想导出构造函数,那么您应该了解使用module.exportsor exports;(再次记住,module.exports当您需要某些东西时将返回它,而不是export)。

module.exports = function Something() {
    console.log('bla bla');
}

现在typeof返回结果是'function',您可以要求它并立即调用:
var x = require('./file1.js')();因为您将返回结果覆盖为一个函数。

但是,使用exports你不能使用类似的东西:

exports = function Something() {
    console.log('bla bla');
}
var x = require('./file1.js')(); //Error: require is not a function

因为有了exports,引用不再指向指向的对象module.exports,所以exports和之间module.exports不再存在关系。在这种情况下module.exports仍然指向{}将返回的空对象。

2022-04-14