Node.js中的module.exports与export

JavaScript

Tony樱番长

2020-03-11

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

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

我不知道什么之间的不同module.exportsexports为什么都被用在这里。

第644篇《Node.js中的module.exports与export》来自Winter(https://github.com/aiyld/aiyld.github.io)的站点

11个回答
小卤蛋卡卡西A 2020.03.11

module.exportsexports在评估模块之前它们都指向同一对象。

module.exports 当您的模块在另一个模块中使用using require语句使用时,添加到对象的任何属性都将可用exports是可用于同一事物的快捷方式。例如:

module.exports.add = (a, b) => a+b

相当于写:

exports.add = (a, b) => a+b

因此,只要您不为exports变量分配新值就可以当您执行以下操作时:

exports = (a, b) => a+b 

由于您正在为其分配新值,exports因此不再引用导出的对象,因此将保留在模块本地。

如果您打算为分配一个新值,module.exports而不是向可用的初始对象添加新属性,则可能应该考虑执行以下操作:

module.exports = exports = (a, b) => a+b

Node.js网站对此有很好的解释。

小小Green 2020.03.11

1.exports->用作单例实用程序
2. module- exports-> 用作逻辑对象,如service,model等

LEYAItachi 2020.03.11

“如果您希望模块导出的根是一个函数(例如构造函数),或者想一次导出一个完整的对象而不是一次构建一个属性,则将其分配给module.exports而不是出口。” - http://nodejs.org/api/modules.html

神奇古一 2020.03.11

这展示了如何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);
凯樱 2020.03.11

来自文档

导出变量在模块的文件级范围内可用,并在评估模块之前为其指定了module.exports的值。

它允许使用快捷方式,以便module.exports.f = ...可以更简洁地编写为exports.f =...。但是,请注意,与任何变量一样,如果将新值分配给exports,不再绑定到module.exports:

它只是指向module.exports的变量。

Sam飞云 2020.03.11

我发现此链接对于回答上述问题很有用。

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应该没问题。

卡卡西逆天十三 2020.03.11

这是结果

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提供的扩展,以支持更广泛的模块定义模式。

番长樱梅 2020.03.11

这是Manning出版的操作手册中有关node.js中的节点模块的良好描述 最终在您的应用程序中导出的是module.exports。可以将exports设置为对module.exports的全局引用,该模块最初定义为可以向其添加属性的空对象。所以exports.myFunc是刚刚速记module.exports.myFunc 其结果是,如果出口被设置为别的,它打破了基准之间 module.exports出口因为module.exports



是真正要导出的内容,导出将不再按预期方式工作-它不再引用.exports模块如果要维护该链接,可以使module.exports再次 引用导出,如下所示:

module.exports = exports = db;
番长西里神无 2020.03.11

JavaScript通过引用的副本传递对象

在JavaScript中通过引用传递对象的方式有微妙的区别。

exportsmodule.exports都指向同一个对象。exports是变量,module.exports是模块对象的属性。

说我写这样的东西:

exports = {a:1};
module.exports = {b:12};

exportsmodule.exports现在指向不同的对象。修改导出不再修改module.exports。

导入功能检查module.exports时得到{b:12}

飞云前端西门 2020.03.11

最初,module.exports=exportsrequire函数会返回所module.exports引用的对象

如果我们向对象添加属性,例如exports.a=1,则module.exports和export 引用同一对象。因此,如果我们调用require并将模块分配给变量,则该变量具有a属性,其值为1;

但是,如果我们覆盖其中的一个,例如,exports=function(){}则它们现在有所不同:export指向一个新对象,而module.exports指向原始对象。如果我们需要该文件,它将不会返回新对象,因为module.exports没有引用新对象。

对我而言,我将继续添加新属性,或将它们都覆盖到新对象中。仅仅覆盖一个是不对的。并记住那module.exports才是真正的老板。

神无 2020.03.11

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() { ... }

问题类别

JavaScript Ckeditor Python Webpack TypeScript Vue.js React.js ExpressJS KoaJS CSS Node.js HTML Django 单元测试 PHP Asp.net jQuery Bootstrap IOS Android