NodeJS / Express中的“module.exports”和“exports.methods”是什么意思?

查看NodeJSexpress框架的随机源文件 ,有两行代码我不明白(这些代码行几乎是所有NodeJS文件的典型代码)。

 /** * Expose `Router` constructor. */ exports = module.exports = Router; 

 /** * Expose HTTP methods. */ var methods = exports.methods = require('./methods'); 

我明白, 第一块代码 允许文件中的其余function暴露给NodeJS应用程序 ,但我不明白如何工作的 ,或者线上的代码是什么意思。

exportsmodule.exports究竟意味着什么?

我相信第二段代码允许文件中的函数访问methods ,但是它又是如何做到这一点的。

基本上,这些魔术词是什么: moduleexports

更具体:

module是文件内的全局范围variables。

所以如果你调用require("foo")那么:

 // foo.js console.log(this === module); // true 

它的行为与window在浏览器中的作用方式相同。

还有另外一个叫做global全局对象,你可以在你想要的任何文件中读写,但涉及到全局范围的变异,这是EVIL

exports是一个生活在module.exports上的variables。 这基本上是您在需要文件时导出的内容。

 // foo.js module.exports = 42; // main.js console.log(require("foo") === 42); // true 

自己的exports有一个小问题。 _global作用域上下文+和module一样的。 (在浏览器中,全局范围上下文和window是相同的)。

 // foo.js var exports = {}; // creates a new local variable called exports, and conflicts with // living on module.exports exports = {}; // does the same as above module.exports = {}; // just works because its the "correct" exports // bar.js exports.foo = 42; // this does not create a new exports variable so it just works 

阅读更多关于出口

为了扩大Raynos的答案

exports基本上是module.exports别名 – 我build议不要使用它。 您可以通过在module.exports上设置它们公开模块中的方法和属性 ,如下所示:

 //file 'module1.js' module.exports.foo = function () { return 'bar' } module.exports.baz = 5 

然后你可以在你的代码中访问它:

 var module1 = require('module1') console.log(module1.foo()) console.log(module1.baz) 

您也可以完全重写 module.exports ,以便在需要时提供单个对象:

 //glorp.js module.exports = function () { this.foo = function () { return 'bar' } this.baz = 5 return this // need to return `this` object here } 

现在你已经有了一个很好的原型:

 var g1 = new require('glorp')() console.log(g1.foo()) console.log(g1.baz) 

有很多其他的方式来玩module.exportsrequire 。 只要记住, require('foo') 总是返回同一个实例,即使你多次调用它。

注意

为了以下的工作,

 var g1 = new require('glorp')() console.log(g1.foo()) console.log(g1.baz) 

this必须在分配给module.exports的函数中返回。 否则,你会得到一个TypeError

 console.log(g1.foo()) ^ TypeError: Cannot read property 'foo' of undefined 

你可以在node.js源代码中find最好的答案。 如果有人需要你的js模块,你的脚本按照如下方式变成一个function节点(见src / node.js)。

 // require function does this.. (function (exports, require, module, __filename, __dirname) { ... your javascript contents... }); 

节点将包装您的脚本。 然后上面的脚本将被执行如下:

 //module.js var args = [self.exports, require, self, filename, dirname]; return compiledWrapper.apply(self.exports, args); 

所以在你的脚本中,

 exports is just module.exports. 

在你的脚本中,你可以添加一些东西到这个导出对象(函数..)。 require函数将返回这个对象。 这是node.js的模块系统(commonJS规范)。

但要小心不要修改module.exports。 否则,你目前的出口将是没有意义的。

模块是一个对象,它表示特定的源文件想要公开的内容。 而不是在c / c ++世界里有类似于头文件的东西,而是通过定义这个对象来描述模块导出的内容。 节点运行时然后使用这个对象来确定你的模块是“公共的”。

其类似的概念,从编译世界中的DLL导出function。 你必须明确地定义外部世界可以访问哪些function。 这有助于封装,并让您以一种干净的方式组织您的图书馆。