前言
在Node.js环境中,module.exports
和 require
是CommonJS模块系统的核心机制,用于模块的导出和导入。以下是对这种导入导出方式的详细介绍:
1. module.exports
用于导出模块内容
module.exports
是一个特殊的对象,它用于定义模块的导出内容。当一个模块被加载时,module.exports
的值会被传递给调用它的模块。
语法
javascript
module.exports = value;
value
可以是任何值,例如对象、函数、类、字符串、数字等。
示例
假设有一个文件 timeHelper.js
,内容如下:
javascript
module.exports = class TimeHelper {
static getCurrentTime() {
return new Date();
}
};
在这个例子中:
- 定义了一个类
TimeHelper
。 - 使用
module.exports
将这个类导出,使得其他模块可以通过require
来加载它。
2. require
用于导入模块
require
是一个全局函数,用于加载模块(注意,是同步加载 !这意味着使用require(xxx)
的时候,代码会发生阻塞,直到加载完成,当然,除了循环依赖
的情况------后面会讲到)。它会读取指定路径的模块文件,并返回模块的导出内容。
语法
javascript
const importedValue = require(modulePath);// 注意 importedValue 可以是任何名称 这并不是具名导出!!但是为了规范 一般建议与导出名字一致
modulePath
是模块的路径,可以是相对路径(如./timeHelper.js
)或绝对路径。importedValue
是模块导出的内容。
示例
在另一个文件中,可以通过 require
导入 timeHelper.js
中的内容:
javascript
const TimeHelper = require('./timeHelper.js');
- 这里
require('./timeHelper.js')
会加载timeHelper.js
文件,并返回module.exports
的值。 - 将返回的值赋值给
TimeHelper
,因此TimeHelper
现在是timeHelper.js
中导出的类。
3. 使用导入的模块
在导入模块后,就可以使用模块中定义的类、函数、对象等。
示例
假设在导入 timeHelper.js
后,需要使用 TimeHelper
类中的静态方法:
javascript
const TimeHelper = require('./timeHelper.js');
console.log(TimeHelper.getCurrentTime()); // 输出当前时间
- 通过
TimeHelper.getCurrentTime()
调用了timeHelper.js
中定义的静态方法。
4. module.exports
和 require
的特点
-
模块缓存机制
-
当一个模块被加载后,它的内容会被缓存。如果同一个模块被多次加载,
require
会返回缓存的值,而不是重新执行模块代码。这可以提高性能,避免重复加载模块。 -
例如:
javascriptconst TimeHelper1 = require('./timeHelper.js'); const TimeHelper2 = require('./timeHelper.js'); console.log(TimeHelper1 === TimeHelper2); // 输出 true
-
-
模块路径解析
- 如果
require
的路径是相对路径(如./timeHelper.js
),Node.js会从当前文件所在目录开始查找。 - 如果路径是文件夹(如
./time
),Node.js会查找该文件夹下的index.js
文件,或者查找package.json
中的main
字段指定的文件。 - 如果路径是模块名称(如
require('fs')
),Node.js会查找内置模块、node_modules
文件夹下的模块等。
- 如果
-
模块加载顺序(后续会解释下)
- 如果模块之间存在循环依赖(即模块A依赖模块B,模块B依赖模块A),Node.js会按照一定的顺序加载模块。在加载过程中,如果遇到循环依赖,会返回当前模块的导出内容(即使模块代码尚未完全执行)。
5. 总结
module.exports
用于定义模块的导出内容,可以导出类、函数、对象等。require
用于加载模块,返回模块的导出内容。
收摊!