Javascript Node.js module.exports的用途是什么?如何使用它?

Javascript Node.js module.exports的用途是什么?如何使用它?,javascript,node.js,Javascript,Node.js,Node.js module.exports的用途是什么?如何使用它 我似乎找不到这方面的任何信息,但它似乎是Node.js的一个相当重要的部分,因为我经常在源代码中看到它 根据报告: 模块 对当前事件的引用 模块。特别是module.exports 与导出对象相同。看见 src/node.js了解更多信息 但这并没有真正的帮助 module.exports到底做什么,一个简单的例子是什么?是实际返回的对象,它是require调用的结果 exports变量最初设置为相同的对象(即,它是一个简写的

Node.js module.exports的用途是什么?如何使用它

我似乎找不到这方面的任何信息,但它似乎是Node.js的一个相当重要的部分,因为我经常在源代码中看到它

根据报告:

模块

对当前事件的引用
模块
。特别是
module.exports
与导出对象相同。看见
src/node.js
了解更多信息

但这并没有真正的帮助

module.exports
到底做什么,一个简单的例子是什么?

是实际返回的对象,它是
require
调用的结果

exports
变量最初设置为相同的对象(即,它是一个简写的“别名”),因此在模块代码中,您通常会编写如下内容:

let myFunc1 = function() { ... };
let myFunc2 = function() { ... };
exports.myFunc1 = myFunc1;
exports.myFunc2 = myFunc2;
exports = module.exports = function(){
    //....
}
// test.js
var name = 'william';

module.exports = function(){
    console.log(name);
}   

// index.js
var test = require('./test');
test();
导出(或“公开”)内部作用域函数
myFunc1
myFunc2

在调用代码中,您将使用:

const m = require('./mymodule');
m.myFunc1();
其中最后一行显示了
require
的结果(通常)只是一个可以访问其属性的普通对象

注意:如果覆盖
导出
,则它将不再引用
模块.导出
。因此,如果您希望将新对象(或函数引用)分配给
exports
,则还应将该新对象分配给
module.exports


值得注意的是,添加到
导出
对象的名称不必与要添加的值的模块内部作用域名称相同,因此您可以:

let myVeryLongInternalName = function() { ... };
exports.shortName = myVeryLongInternalName;
// add other objects, functions, as required
其次是:

const m = require('./mymodule');
m.shortName(); // invokes module.myVeryLongInternalName

这已经得到了回答,但我想补充一些澄清

您可以同时使用
导出
模块。导出
将代码导入应用程序,如下所示:

let myFunc1 = function() { ... };
let myFunc2 = function() { ... };
exports.myFunc1 = myFunc1;
exports.myFunc2 = myFunc2;
exports = module.exports = function(){
    //....
}
// test.js
var name = 'william';

module.exports = function(){
    console.log(name);
}   

// index.js
var test = require('./test');
test();
var mycode=require('./path/to/mycode')

您将看到的基本用例(例如,在ExpressJS示例代码中)是在.js文件中的
导出
对象上设置属性,然后使用
require()

因此,在一个简单的计数示例中,您可以:

let myVeryLongInternalName = function() { ... };
exports.shortName = myVeryLongInternalName;
// add other objects, functions, as required
(counter.js):

。。。然后在您的应用程序(web.js或任何其他.js文件)中:

简单地说,您可以将所需的文件视为返回单个对象的函数,并且您可以通过将属性(字符串、数字、数组、函数等)设置为“导出”
,向返回的对象添加属性

有时,您希望从
require()
调用返回的对象是可以调用的函数,而不仅仅是具有属性的对象。在这种情况下,还需要设置
module.exports
,如下所示:

let myFunc1 = function() { ... };
let myFunc2 = function() { ... };
exports.myFunc1 = myFunc1;
exports.myFunc2 = myFunc2;
exports = module.exports = function(){
    //....
}
// test.js
var name = 'william';

module.exports = function(){
    console.log(name);
}   

// index.js
var test = require('./test');
test();
(sayhello.js):

(app.js):


exports和module.exports之间的区别在中得到了更好的解释。

请注意,NodeJS模块机制基于许多其他实现中支持的模块,如RequireJS,但也支持SproutCoreCouchDBWakandaOrientDBArangoDBRingoJSTeaJSSilkJScurl.js,甚至Adobe Photoshop(via)。 您可以找到已知实现的完整列表

除非您的模块使用特定于节点的功能或模块,否则我强烈建议您使用
导出
,而不是
模块。导出
,它不属于CommonJS标准,并且大多数情况下不受其他实现的支持

NodeJS特有的另一个特性是,当您将对新对象的引用指定给
exports
时,而不是像Jed Watson在本线程中提供的最后一个示例那样,仅向其添加属性和方法。我个人不鼓励这种做法,因为它打破了CommonJS模块机制的循环引用支持。因此,并不是所有的实现都支持它,然后应该以这种方式(或类似方式)编写Jed示例,以提供更通用的模块:

(sayhello.js):

(app.js):

或者使用ES6功能

(sayhello.js):

(app.js):


PS:Appcelerator似乎也实现了CommonJS模块,但没有循环引用支持(请参见:)

如果将引用分配给新对象,则必须注意以下几点:导出和/或
模块。导出

1.以前附加到原始
导出
模块的所有属性/方法。导出
当然会丢失,因为导出的对象现在将引用另一个新对象 这一点很明显,但是如果在现有模块的开头添加导出方法,请确保本机导出的对象没有在结尾引用另一个对象

exports.method1 = function () {}; // exposed to the original exported object
exports.method2 = function () {}; // exposed to the original exported object

module.exports.method3 = function () {}; // exposed with method1 & method2

var otherAPI = {
    // some properties and/or methods
}

exports = otherAPI; // replace the original API (works also with module.exports)
2.如果
导出
module.exports
中的一个引用了一个新值,则它们不再引用同一对象 3.棘手的后果。如果将引用同时更改为
exports
module.exports
,则很难说暴露了哪个API(看起来像
module.exports
赢了)
module.exports属性或exports对象允许模块选择应与应用程序共享的内容


我有一个关于模块导出的视频可用

参考链接如下:

let myFunc1 = function() { ... };
let myFunc2 = function() { ... };
exports.myFunc1 = myFunc1;
exports.myFunc2 = myFunc2;
exports = module.exports = function(){
    //....
}
// test.js
var name = 'william';

module.exports = function(){
    console.log(name);
}   

// index.js
var test = require('./test');
test();
导出
模块的属性。导出
,例如函数或变量,将在外部公开

有一点您必须更加注意:不要覆盖导出

为什么?

由于只导出module.exports的引用,因此可以将属性添加到导出中,但如果覆盖导出,则引用链接将断开

好例子:

exports.name = 'william';

exports.getName = function(){
   console.log(this.name);
}
exports = 'william';

exports = function(){
     //...
}
ba
sayHelloInEnglish = function() {
  return "Hello";
};
sayHelloInSpanish = function() {
  return "Hola";
};
var anyVariable={
 sayHelloInEnglish = function() {
      return "Hello";
    };
  sayHelloInSpanish = function() {
      return "Hola";
    }; 
}
module.export=anyVariable;
var world= require("./hello.js");
exports.additionTwo = function(x)
{return x+2;};
exports.additionTwo = function(x){
return x + 2;
};
node
var run = require('addition.js');
set NODE_PATH = path/to/your/additon.js
node
var run = require('./addition.js');
function log(string) { require('fs').appendFileSync('log.txt',string); }

module.exports = log;
function log(string) { console.log(string); }

module.exports = log;
const log = require('./stdoutLog.js')

log('hello world!');
const test2 = require('./test2');    // returns the module.exports object of a file

test2.Func1(); // logs func1
test2.Func2(); // logs func2
module.exports.Func1 = () => {console.log('func1')};

exports.Func2 = () => {console.log('func2')};
let test = function() {
    return "Hello world"
};
exports.test = test;