Nodejs模块载入运行原理


Posted in NodeJs onFebruary 23, 2018

前言

使用Nodejs,就不可避免地引用第三方模块,它们有些是Nodejs自带的(例:http,net...),有些是发布在npm上的(例:mssql,elasticsearch...)

本篇章聚焦3个问题:

  1. Nodejs模块的加载过程。
  2. 应用启动的过程。
  3. 应用如何加载依赖模块。

1.模块的加载过程

Nodejs 模块大概可分为4种:

a) builtin module Nodejs中以C++形式提供的模块。

b) constant module Nodejs中定义常量的模块。

c) native module Nodejs中以javascript形式提供的模块。

d) 第三方module 由第三方提供的模块。

我们先看builtin module 和 native module的生成过程。

Nodejs模块载入运行原理

native JS module的生成相对复杂一些,编译后,会在/out/release/obj/gen目录下生成一个node_natives.h。

该文件是由js2c.py生成,它会把Nodejs源码中的lib目录下,所有js文件转成ASCII码,并存放在相应的数组里。

Nodejs模块载入运行原理

builtin C++ module 生成过程相对简单,每个builtin C++的模块入口,都会通过宏NODE_MODULE_CONTEXT_AWARE_BUILTIN扩展成一个func,例如对tcp_wrap模块而言,会扩展成static void register_tcp_wrap() attribute(constructor) 函数。

熟悉GCC的朋友都知道,attribute(constructor)修饰的函数会在Nodejs的main()函数之前被执行,也就是说,builtin C++ module 会在main()函数之前被载入到modlist_builtin列表,而modlist_builtin是一个struct node_module类型的指针,get_builtin_module()会遍历查找我们所需的模块。

其实无论是naive JS module 还是 builtin C++ module,最终都是要被编译成可执行文件。对于两者的提取方式,却大不相同,js module 使用process.binding('natives'),而C++ module 则直接使用get_builtin_module()。

在node.cc里面提供了一个binding()函数,当我们应用require()来引用另外一个模块时,binding()函数便会被引入。下面我们分析一下这个函数:

Nodejs模块载入运行原理

可以目测到,函数主要为三个模块服务:builtin,constants和native。

builtin优先级最高,会到modlist_builtin中查找,过程非常简单,遍历整个列表,查找相同名字的模块即可。找到后,模块的注册函数会被先执行,然后将数据exports返回。

constants模块优先级次之,Nodejs中的常量定义通过constants导出。

native 优先级最低。

2.应用启动的过程

Nodejs模块载入运行原理

上图为一个流程图,它描述了test.js做为参数启动开始,最终被执行。整个过程可以分为4步:

1.可执行文件 node : node入口,在启动过程中主要扮演环境准备工作

2.src/node.js:启动脚本

3.Native Module:为module.js 的执行做准备工作

4.module.js:native module,用来加载,编译,执行应用程序

应用如何加载依赖模块

前面提到NativeModule.require()只负责帮助引用natives module,这对于lib/module.js而言已经足够了。

但是很明显,一般应用不但需要引用matives module,还要引用第三方模块,让我们看一下module.js中的Module.prototype._require()函数中。

Nodejs模块载入运行原理

NodeJs 相关文章推荐
基于promise.js实现nodejs的promises库
Jul 06 NodeJs
nodejs 实现模拟form表单上传文件
Jul 14 NodeJs
Nodejs学习笔记之Global Objects全局对象
Jan 13 NodeJs
NodeJS学习笔记之Connect中间件应用实例
Jan 27 NodeJs
NodeJS Web应用监听sock文件实例
Feb 18 NodeJs
nodejs通过phantomjs实现下载网页
May 04 NodeJs
nodejs初步体验篇
Nov 23 NodeJs
nodejs实现发出蜂鸣声音(系统报警声)的方法
Jan 18 NodeJs
Nodejs+Socket.io实现通讯实例代码
Feb 13 NodeJs
NodeJS实现不可逆加密与密码密文保存的方法
Mar 16 NodeJs
nodejs实现范围请求的实现代码
Oct 12 NodeJs
Nodejs实现图片上传、压缩预览、定时删除功能
Oct 25 NodeJs
Nodejs下使用gm圆形裁剪并合成图片的示例
Feb 22 #NodeJs
nodejs微信扫码支付功能实现
Feb 17 #NodeJs
nodejs+express搭建多人聊天室步骤
Feb 12 #NodeJs
nodeJs实现基于连接池连接mysql的方法示例
Feb 10 #NodeJs
NodeJS简单实现WebSocket功能示例
Feb 10 #NodeJs
nodejs使用redis作为缓存介质实现的封装缓存类示例
Feb 07 #NodeJs
nodejs中Express与Koa2对比分析
Feb 06 #NodeJs
You might like
咖啡与水的关系
2021/03/03 冲泡冲煮
php 获取客户端的真实ip
2009/11/30 PHP
thinkphp3.2.2前后台公用类架构问题分析
2014/11/25 PHP
PHP编程文件处理类SplFileObject和SplFileInfo用法实例分析
2017/07/22 PHP
PHP获取php,mysql,apche的版本信息及更多服务器信息
2021/03/09 PHP
js鼠标点击事件在各个浏览器中的写法及Event对象属性介绍
2013/01/24 Javascript
简单实用的全选反选按钮例子
2013/10/18 Javascript
JQuery EasyUI 加载两次url的原因分析及解决方案
2014/08/18 Javascript
jquery+CSS实现的水平布局多级网页菜单效果
2015/08/24 Javascript
bootstrap3 dialog 更强大、更灵活的模态框
2017/04/20 Javascript
详谈表单重复提交的三种情况及解决方法
2017/08/16 Javascript
vue使用混入定义全局变量、函数、筛选器的实例代码
2019/07/29 Javascript
vue addRoutes路由动态加载操作
2020/08/04 Javascript
[51:20]完美世界DOTA2联赛PWL S2 Magma vs PXG 第一场 11.28
2020/12/01 DOTA
Python文件和目录操作详解
2015/02/08 Python
常见的在Python中实现单例模式的三种方法
2015/04/08 Python
在Python中处理字符串之isdecimal()方法的使用
2015/05/20 Python
qpython3 读取安卓lastpass Cookies
2016/06/19 Python
python调用系统ffmpeg实现视频截图、http发送
2018/03/06 Python
python smtplib发送带附件邮件小程序
2018/05/22 Python
Python基于jieba库进行简单分词及词云功能实现方法
2018/06/16 Python
Python实战之制作天气查询软件
2019/05/14 Python
关于python tushare Tkinter构建的简单股票可视化查询系统(Beta v0.13)
2020/10/19 Python
10个示例带你掌握python中的元组
2020/11/23 Python
Gretna Green中文官网:苏格兰格林小镇
2019/10/16 全球购物
日本最大的彩色隐形眼镜销售网站:CharmColor
2020/09/09 全球购物
银行职业规划书范文
2013/12/28 职场文书
新闻学专业大学生职业生涯规划范文
2014/03/02 职场文书
家长会学生演讲稿
2014/04/26 职场文书
大学生就业自荐书
2014/06/16 职场文书
领导干部学习“三严三实”思想汇报
2014/09/15 职场文书
《角的度量》教学反思
2016/02/18 职场文书
oracle表分区的概念及操作
2021/04/24 Oracle
Python连续赋值需要注意的一些问题
2021/06/03 Python
浅谈sql_@SelectProvider及使用注意说明
2021/08/04 Java/Android
分析SQL窗口函数之排名窗口函数
2022/04/21 Oracle