CommonJS概念
在 Node.js 中,CommonJS 是一种模块化规范,它定义了如何在 JavaScript 中创建和使用模块。CommonJS 是 Node.js 使用的默认模块系统。它让开发者能够分离代码,便于重用和维护。
CommonJS 模块的基本特性
模块导出
在 CommonJS 模块系统中,
module.exports
和exports
都是用于导出模块内容的对象,但它们有一些关键的区别。在大多数情况下,二者行为相似,但它们的使用方式和语义有所不同。理解这两者的区别非常重要,尤其是在导出多个功能或自定义导出时。
1、module.exports
和 exports
的关系
exports
是module.exports
的一个引用,最初它们指向同一个对象。module.exports
是模块的最终导出对象,最终通过require()
引用模块时返回的内容就是module.exports
的值。exports
是module.exports
的一个快捷引用,可以用来简化导出语法。
2、关键区别
-
初始化时的关系:
- 在每个模块加载时,Node.js 会自动创建一个
module.exports
对象,并且exports
是module.exports
的引用(即exports === module.exports
)。 - 你可以通过
exports
添加属性和方法,这样module.exports
对象也会自动更新。
- 在每个模块加载时,Node.js 会自动创建一个
-
直接赋值的区别:
- 如果你直接修改
module.exports
(例如,给module.exports
赋一个新的对象),exports
将不再与module.exports
保持引用关系。此时,exports
和module.exports
不再指向同一个对象。 - 但是,如果你修改
exports
里的属性(例如,exports.add = ...
),那么这会影响module.exports
。
- 如果你直接修改
模块导入
使用
require()
函数导入模块。
// app.js
const math = require('./math');
console.log(math.add(1, 2)); // 输出: 3
console.log(math.subtract(5, 3)); // 输出: 2
CommonJS 模块的关键点
-
同步加载
CommonJS 模块是同步加载的。这意味着,当require()
被调用时,Node.js 会同步地加载并执行模块代码,然后返回模块的导出内容。 -
每个模块只加载一次
在 Node.js 中,一个模块会被加载并执行一次。之后,对于同一个模块的任何后续require()
调用,都会返回相同的模块缓存(module.exports
)。这可以提高性能,因为同一模块的代码不会被执行多次。 -
模块作用域
每个模块都有自己的作用域。模块内的变量和函数不会泄露到全局作用域,只能通过module.exports
导出访问。这样可以避免命名冲突。