在NodeJS/Express中,"module.exports"和"exports.methods"是什么意思?

mrw*_*ter 56 javascript module export node.js express

看着一个随机的源文件中的express为框架NodeJS,有我不理解的代码的两行(这行代码是典型的几乎所有文件的NodeJS).

/**
 * Expose `Router` constructor.
 */

exports = module.exports = Router;
Run Code Online (Sandbox Code Playgroud)

/**
 * Expose HTTP methods.
 */

var methods = exports.methods = require('./methods');
Run Code Online (Sandbox Code Playgroud)

我知道第一段代码 允许文件中的其余函数暴露给NodeJS应用程序,但我不明白如何工作的,或者行中的代码意味着什么.

做什么exportsmodule.exports实际意味着什么?

我相信第二段代码允许文件中的函数访问methods,但同样,它是如何做到的.

基本上,这些神奇的词是什么:moduleexports

Ray*_*nos 79

更具体:

module 是文件中的全局范围变量.

所以,如果你打电话require("foo"):

// foo.js
console.log(this === module); // true
Run Code Online (Sandbox Code Playgroud)

它的行为方式window与浏览器中的行为方式相同.

还有另一个全局对象global,您可以在任何文件中编写和读取,但这涉及到变异全局范围,这就是EVIL

exports是一个存在的变量module.exports.它基本上是在需要文件时导出的内容.

// foo.js
module.exports = 42;

// main.js
console.log(require("foo") === 42); // true
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

详细了解出口情况


Tam*_*ake 34

扩展Raynos的答案......

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

//file 'module1.js'
module.exports.foo = function () { return 'bar' }
module.exports.baz = 5
Run Code Online (Sandbox Code Playgroud)

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

var module1 = require('module1')
console.log(module1.foo())
console.log(module1.baz)
Run Code Online (Sandbox Code Playgroud)

您还可以 module.exports完全覆盖以根据需要提供单个对象:

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

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

var g1 = new require('glorp')()
console.log(g1.foo())
console.log(g1.baz)
Run Code Online (Sandbox Code Playgroud)

有无数其他方式可以玩module.exportsrequire.请记住,即使您多次调用它,也require('foo') 始终返回相同的实例.

注意

为了以下工作,

var g1 = new require('glorp')()
console.log(g1.foo())
console.log(g1.baz) 
Run Code Online (Sandbox Code Playgroud)

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

console.log(g1.foo())
          ^
TypeError: Cannot read property 'foo' of undefined
Run Code Online (Sandbox Code Playgroud)


jer*_*yko 15

您可以在node.js源代码中找到最佳答案.如果有人需要你的js模块,你的脚本将按节点变为一个函数,如下所示(参见src/node.js).

// require function does this..
(function (exports, require, module, __filename, __dirname) {
    ... your javascript contents...
});
Run Code Online (Sandbox Code Playgroud)

Node将包装你的脚本.然后上面的脚本将执行如下:

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

所以在你的脚本中,

exports is just module.exports.
Run Code Online (Sandbox Code Playgroud)

在您的脚本中,您可以向此导出对象添加一些内容(函数..).require函数将返回此对象.这是node.js的模块系统(commonJS规范).

但要注意不要修改module.exports.否则你当前的出口将毫无意义.