什么是“;module.exports”;以及“;exports.methods”;NodeJS/Express中的平均

What do "module.exports" and "exports.methods" mean in NodeJS / Express?

本文关键字:exports Express 以及 module 什么 methods NodeJS      更新时间:2023-09-26

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

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

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

我知道第一段代码允许文件中的其余函数暴露给NodeJS应用程序,但我不完全理解它是如何工作的或这行代码的含义。

exportsmodule.exports实际上是什么意思?

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

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

更具体地说:

module是文件中的全局作用域变量。

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

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

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

还有另一个名为global的全局对象,您可以在任何想要的文件中进行写入和读取,但这涉及到全局范围的变化,这就是EVIL

CCD_ 12是一个存在于CCD_ 13上的变量。当需要文件时,这基本上就是导出的内容。

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

exports本身有一个小问题。_global scope context+和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别名-我建议不要使用它。您可以通过在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)

使用CCD_ 21和CCD_ 22还有无数其他方式。请记住,require('foo')总是返回同一个实例,即使您多次调用它也是如此。

备注

为了使以下各项发挥作用,

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

CCD_ 24必须在分配给CCD_ 25的函数中返回。否则,您将获得TypeError:

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

您可以在node.js源代码中找到最佳答案。如果有人需要你的js模块,您的脚本按节点转换为一个函数,如下所示(请参见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导出函数。您必须明确定义外部世界可以访问哪些函数。这有助于封装,并使您能够以干净的方式组织库。

模块的代码封装在模块中。exports(该模块可能由其他模块组成)。有很多方法可以构建模块,但这是一种非常常见的方法(也是我个人最喜欢的方法)。

// Dependencies
// const module = require('module');
// Module object
var foo = {}
// Internal property
foo._a = 'a';
// "Public" property
foo.b = 'b';
// Method
foo.fu = function() { return 'fu' };
// Export
module.exports = foo;