Node.js模块载入与运行原理深度解析
本文深入解析Node.js模块的加载与运行原理,涵盖内置模块、原生JS模块及第三方模块的生成与加载流程。重点分析node.cc中binding()函数的优先级逻辑,以及应用启动时从环境准备到module.js执行的全过程,揭示依赖模块加载的核心机制。
前言
在使用Node.js开发时,引用第三方模块是常见操作。这些模块既包括Node.js自带的核心模块(如http、net等),也包含发布在npm仓库上的第三方库(如mssql、elasticsearch等)。
本文将聚焦探讨以下三个核心问题:
- Node.js模块的具体加载流程。
- 应用程序的启动流程。
- 应用程序如何加载其依赖的模块。
1. 模块的加载过程
Node.js中的模块大致可分为以下四类:
a) 内置模块(Builtin Module):以C++形式提供的Node.js核心模块。
b) 常量模块(Constant Module):用于定义Node.js常量的模块。
c) 原生JS模块(Native JS Module):以JavaScript形式提供的Node.js模块。
d) 第三方模块(Third-party Module):由第三方开发者提供的模块。
接下来,我们将首先分析内置模块和原生JS模块的生成过程。

原生JS模块的生成过程相对复杂。编译完成后,系统会在/out/release/obj/gen目录下生成一个名为node_natives.h的文件。
该文件由js2c.py脚本生成,其作用是将Node.js源码中lib目录下的所有JavaScript文件转换为ASCII码,并将其存储在相应的数组中。

相比之下,内置C++模块的生成过程较为简单。每个内置C++模块的入口点都会通过宏NODE_MODULE_CONTEXT_AWARE_BUILTIN扩展为一个函数。例如,对于tcp_wrap模块,它会扩展为static void register_tcp_wrap() attribute(constructor)函数。
熟悉GCC编译器的读者知道,被attribute(constructor)修饰的函数会在Node.js的main()函数之前执行。这意味着内置C++模块会在main()函数执行前被加载到modlist_builtin列表中。modlist_builtin是一个指向struct node_module类型的指针,get_builtin_module()函数会遍历该列表以查找所需的模块。
无论是原生JS模块还是内置C++模块,最终都会被编译为可执行文件。然而,两者的提取方式截然不同:JS模块通过process.binding('natives')获取,而C++模块则直接使用get_builtin_module()函数。
在node.cc文件中提供了一个binding()函数,当应用程序通过require()引用其他模块时,该函数会被调用。下面我们将分析这个函数的具体实现:

从代码中可以观察到,该函数主要服务于三类模块:内置模块(builtin)、常量模块(constants)和原生JS模块(native)。
内置模块具有最高优先级,系统会在modlist_builtin中查找。这个过程非常简单,即遍历整个列表以查找同名模块。找到后,先执行模块的注册函数,然后返回其导出的数据。
常量模块的优先级次之,Node.js中的常量定义通过constants模块导出。
原生JS模块的优先级最低。
2. 应用启动的过程

上图展示了一个流程图,描述了以test.js为参数启动Node.js并最终执行的全过程。整个过程可划分为四个步骤:
1. 可执行文件node:作为Node.js入口,在启动过程中主要承担环境准备的职责。
2. src/node.js:启动脚本,负责初始化启动流程。
3. 原生模块(Native Module):为module.js的执行做准备工作。
4. module.js:作为原生模块,负责加载、编译并执行应用程序代码。
应用如何加载依赖模块
前文提到,NativeModule.require()仅负责帮助引用原生JS模块,这对于lib/module.js而言已经足够。
然而,显然一般应用程序不仅需要引用原生JS模块,还需要引用第三方模块。让我们查看module.js中Module.prototype._require()函数的实现细节。

macOS卸载Node.js指南:区分Homebrew与pkg安装包的处理方式
2026-11-05 11:28:12
JS逆向入门:浏览器Console调试与Node.js环境搭建指南
2026-11-05 10:57:15
Node.js 大版本升级需要注意哪些破坏性变更
2026-11-03 20:35:44
Node.js官网LTS版与Current版有什么区别
2026-11-03 19:33:49
Windows彻底卸载Node.js:清理AppData残留与PATH环境变量
2026-11-03 19:15:35
