title: Node.js 源码分析 - 从 main 函数开始 date: 2018-11-27 21:30:15 tags: - Node.js - Node.js 源码分析 - 源码分析 categories: - Node.js 源码分析
此文最初于四年前发布在个人站上的,现迁移至此重发,原链接: https://laogen.site/nodejs/nodejs-src/the-main/ 《Node.js 源码分析》 系列目录页:https://laogen.site/nodejs/nodejs-src/index/
小目标
知道程序大概执行逻辑,关键点执行的顺序
我们平时在终端敲下 node app.js
后,发生了什么。
具体点,知道 node.js 原生(C++)模块什么时候加载的,在哪加载的; 知道我们的 js 代码是在哪个环节被加载执行的; 知道进程的主循环(事件循环)什么时候启动的;
有了这个小目标的基础,在接下来的文章中,我们再进一步的探索 node.js 原生模块的注册是怎么实现的,怎么获取 & 初始化的,怎么曝露给 js 环境调用的;再细说 node.js 的模块机制,我们通常的 app.js
怎么被执行的;
贴代码说明
限于篇幅,本文只先把大体执行流程捋出来,后面再开文一块块的捋。
原代码太长,先把不影响我们分析的无关代码去掉,贴上来有关整体执行逻辑的代码,代码中的 // ...
注释意思是这个地方有被省略的代码。
每段代码第一行的注释都会指出源文件位置,一些代码讲解会在代码段中的注释中进行;
本文不再介绍 V8 和 Libuv 的知识,会开专门的分类写 V8 和 Libuv,参考 {% post_link nodejs/nodejs-src/index Node.js 源码分析 - 前言 %}
开捋:从 main 函数到进程主循环
main 函数
/* src/node_main.cc:93 */
int main(int argc, char* argv[]) {
// ...
return node::Start(argc, argv);
}
main函数
在 src/node_main.cc
这个文件中,这个文件主要就是存放 main函数
。
很简单,只是调用了 node::Start()
,这个函数在 src/node.cc
这个文件中,接下来的核心代码都在这个文件中。
初始化 V8 引擎
/* src/node.cc:3011 */
int Start(int argc, char** argv) {
// ...
std::vector<std::string> args(argv, argv + argc);
std::vector<std::string> exec_args;
// This needs to run *before* V8::Initialize().
Init(&args, &exec_args);
// ...
v8_platform.Initialize(per_process_opts->v8_thread_pool_size);
V8::Initialize();