我在Node.js模块中找到了以下契约:

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

我想知道module.exports和exports之间有什么区别,为什么在这里使用它们。


当前回答

为什么这两个都用在这里

我相信他们只是想清楚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');说你好;//你好,世界

其他回答

这是曼宁出版的动作书中关于node.js中节点模块的一个很好的描述。最终在应用程序中导出的是module.exports.exportsup简单地作为module.exports的全局引用,它最初定义为可以向其中添加财产的空对象。所以exports.myFunc只是一种速记对于module.exports.myFunc。因此,如果将导出设置为其他值,则会断开引用模块导出和导出。因为module.exports是真正的导出,导出将不再按预期工作,它不引用模块.不再导出。如果要维护该链接,可以创建module.exports再次引用导出如下:

module.exports = exports = db;

设置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可以保存字符并避免混淆。

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

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应该可以

1.导出->用作单例实用程序2.模块导出->用作逻辑对象,如服务、模型等

这显示了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);