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

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

根据Node.js文档:

单元参考电流单元特别是module.exports与导出对象相同。看见src/node.js获取更多信息。

但这并没有真正的帮助。

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


当前回答

目的是:

模块化编程是一种强调将程序的功能分离成独立的,可互换的模块,每个模块都包含所有必要的内容以仅执行期望功能的一个方面。

维基百科

我想,如果没有模块化/可重用代码,编写大型程序会变得困难。在nodejs中,我们可以使用module.exports创建模块化程序,该模块定义了我们公开的内容,并使用require编写程序。

请尝试以下示例:

文件日志.js

function log(string) { require('fs').appendFileSync('log.txt',string); }

module.exports = log;

标准输出日志.js

function log(string) { console.log(string); }

module.exports = log;

程序.js

const log = require('./stdoutLog.js')

log('hello world!');

处决

$node程序.js你好,世界!

现在尝试交换/的stdoutLog.js/fileLog.js。

其他回答

参考链接如下:

exports = module.exports = function(){
    //....
}

导出或模块的财产。导出,例如函数或变量,将在外部公开

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

为什么?

因为导出只是module.exports的引用,所以可以将财产添加到导出中,但如果覆盖导出,引用链接将断开。

很好的例子:

exports.name = 'william';

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

坏例子:

exports = 'william';

exports = function(){
     //...
}

如果您只想公开一个函数或变量,如下所示:

// test.js
var name = 'william';

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

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

这个模块只公开了一个函数,name的属性对外是私有的。

module.exports属性或exports对象允许模块选择应该与应用程序共享的内容

我这里有关于module_export的视频

let test = function() {
    return "Hello world"
};
exports.test = test;

如果将对新对象的引用分配给exports和/或modules.exports,则必须注意以下几点:

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.如果exports或module.exports中的一个引用新值,则它们不再引用同一对象

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

// method added to the original exports object which not exposed any more
module.exports.method3 = function () {}; 

3.狡猾的后果。如果同时更改了对exports和module.exports的引用,很难说哪个API是公开的(看起来module.export获胜)

// override the original exported object
module.exports = function AConstructor() {};

// try to override the original exported object
// but module.exports will be exposed instead
exports = function AnotherConstructor() {}; 

ECMAScript模块-2022

从Node 14.0开始,ECMAScript模块不再是实验性的,您可以使用它们代替经典Node的CommonJS模块。

ECMAScript模块是打包JavaScript代码以供重用的官方标准格式。模块是使用各种导入和导出语句定义的。

您可以定义导出函数的ES模块:

// my-fun.mjs
function myFun(num) {
  // do something
}

export { myFun };

然后,您可以从my-fun.mjs导入导出的函数:

// app.mjs
import { myFun } from './my-fun.mjs';

myFun();

.mjs是Node.js ECMAScript模块的默认扩展名。但是,在使用package.json“type”字段或CLI中的--input-type标志解析模块时,可以将默认模块扩展配置为查找。

Node.js的最新版本完全支持ECMAScript和CommonJS模块。此外,它还提供了它们之间的互操作性。

模块导出

ECMAScript和CommonJS模块有很多不同之处,但与此问题最相关的区别是,不再需要,不再导出,不再模块。导出

在大多数情况下,ES模块导入可用于加载CommonJS模块。如果需要,可以使用module.createRequire()在ES模块中构造require函数。

ECMAScript模块发布历史记录

Release Changes
v15.3.0, v14.17.0, v12.22.0 Stabilized modules implementation
v14.13.0, v12.20.0 Support for detection of CommonJS named exports
v14.0.0, v13.14.0, v12.20.0 Remove experimental modules warning
v13.2.0, v12.17.0 Loading ECMAScript modules no longer requires a command-line flag
v12.0.0 Add support for ES modules using .js file extension via package.json "type" field
v8.5.0 Added initial ES modules implementation

您可以在Node.js存储库中找到所有变更日志