Node.js 模块导入的基本流程
Node.js 模块导入的基本流程,主要是 CommonJS 模块加载机制(即使用 require()
)的内部执行步骤。下面我用清晰的结构给你梳理一下这个过程:
✅ Node.js 模块导入的基本流程(使用 require()
)
const someModule = require('./someModule');
👣 加载流程详解:
① 解析模块路径
- Node.js 会先判断传入的是:
- 核心模块(如
fs
,http
等); - 第三方模块(node_modules 中找);
- 相对路径模块(以
./
或../
开头); - 绝对路径模块(如
/Users/...
)。
- 核心模块(如
② 定位文件(模块路径解析)
- 以相对路径为例:
require('./someModule')
,Node.js 会尝试依次查找以下几种形式:
./someModule.js
./someModule.json
./someModule.node
./someModule/index.js # 如果是目录
③ 缓存检查
- Node.js 会先查看该模块是否已在 缓存 中(
require.cache
)。 - 如果存在缓存,则直接返回缓存结果(即模块导出的对象)。
④ 编译模块
- Node.js 根据不同文件类型执行不同的加载方式:
文件类型 | 加载方式 |
---|---|
.js | 作为 JavaScript 代码加载(包一层函数) |
.json | 使用 JSON.parse() 解析为对象 |
.node | 使用 C++ 插件方式加载(动态链接库) |
- 对于
.js
文件,Node.js 会将模块代码包装成如下形式:
(function(exports, require, module, __filename, __dirname) {// 原始模块代码
})
这叫做 模块包装(Module Wrapper),让模块拥有自己的作用域。
⑤ 执行模块代码
- 在模块包装完成后,Node.js 执行模块代码,并把
module.exports
作为结果返回。
⑥ 返回 exports
对象
- 最终,
require()
返回的是module.exports
的内容。
💡 一个完整的生命周期图示(简略):
require() 调用↓
路径解析↓
缓存检查(require.cache)↓
文件定位(.js/.json/.node)↓
模块包装(function wrapper)↓
模块执行(module.exports)↓
结果返回
🧠 补充:模块缓存细节
- 所有加载过的模块都会被缓存(除非手动清理):
delete require.cache[require.resolve('./someModule')];