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 相关文章推荐
nodejs中使用多线程编程的方法实例
Mar 24 NodeJs
nodejs修复ipa处理过的png图片
Feb 17 NodeJs
Nodejs下用submit提交表单提示cannot post错误的解决方法
Nov 21 NodeJs
搭建简单的nodejs http服务器详解
Mar 09 NodeJs
nodejs Assert中equal(),strictEqual(),deepEqual(),strictDeepEqual()比较
Sep 18 NodeJs
详解nodejs通过代理(proxy)发送http请求(request)
Sep 22 NodeJs
nodejs实现大文件(在线视频)的读取
Oct 16 NodeJs
nodejs+mongodb+vue前后台配置ueditor的示例代码
Jan 02 NodeJs
nodejs实现一个word文档解析器思路详解
Aug 14 NodeJs
基于nodejs的雪碧图制作工具的示例代码
Nov 05 NodeJs
Nodejs让异步变成同步的方法
Mar 02 NodeJs
nodejs中各种加密算法的实现详解
Jul 11 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
php判断ip黑名单程序代码实例
2014/02/24 PHP
php的慢速日志引起的Mysql错误问题分析
2014/05/13 PHP
golang、python、php、c++、c、java、Nodejs性能对比
2017/03/12 NodeJs
PHP MVC框架中类的自动加载机制实例分析
2019/09/18 PHP
Iframe thickbox2.0使用的方法
2009/03/05 Javascript
Javascript 验证上传图片大小[客户端]
2009/08/01 Javascript
jquery $.each 和for怎么跳出循环终止本次循环
2013/09/27 Javascript
使用原生js实现页面蒙灰(mask)效果示例代码
2014/06/20 Javascript
javascript页面倒计时实例
2015/07/25 Javascript
JS实现超简单的汉字转拼音功能示例
2016/12/22 Javascript
Vue原理剖析 实现双向绑定MVVM
2017/05/03 Javascript
微信JS SDK接入的几点注意事项(必看篇)
2017/06/23 Javascript
JS块级作用域和私有变量实例分析
2019/05/11 Javascript
仿iPhone通讯录制作小程序自定义选择组件的实现
2019/05/23 Javascript
详解vuex数据传输的两种方式及this.$store undefined的解决办法
2019/08/26 Javascript
[01:01:51]EG vs VG Supermajor小组赛B组 BO3 第二场 6.2
2018/06/03 DOTA
学习python (1)
2006/10/31 Python
在Python中操作列表之List.append()方法的使用
2015/05/20 Python
Python中的左斜杠、右斜杠(正斜杠和反斜杠)
2016/08/30 Python
Python装饰器原理与用法分析
2018/04/30 Python
Python延时操作实现方法示例
2018/08/14 Python
Django中如何防范CSRF跨站点请求伪造攻击的实现
2019/04/28 Python
django框架实现模板中获取request 的各种信息示例
2019/07/01 Python
Pycharm+Python+PyQt5使用详解
2019/09/25 Python
如何基于pythonnet调用halcon脚本
2020/01/20 Python
Python搭建Keras CNN模型破解网站验证码的实现
2020/04/07 Python
Python参数传递对象的引用原理解析
2020/05/22 Python
python里glob模块知识点总结
2021/01/05 Python
大学生护理专业自荐信
2013/10/03 职场文书
创伤外科专业推荐信范文
2013/11/19 职场文书
养殖项目策划书范文
2014/01/13 职场文书
美丽家庭事迹材料
2014/05/03 职场文书
挂职个人工作总结
2015/03/05 职场文书
消费者理赔投诉书
2015/07/02 职场文书
关于Python中进度条的六个实用技巧分享
2022/04/05 Python
Win11 21h2可以升级22h2吗?看看你的电脑符不符合要求
2022/07/07 数码科技