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 07 NodeJs
NodeJS中Buffer模块详解
Jan 07 NodeJs
windows下安装nodejs及框架express
Aug 07 NodeJs
基于nodejs+express(4.x+)实现文件上传功能
Nov 23 NodeJs
nodejs 中模拟实现 emmiter 自定义事件
Feb 22 NodeJs
详解nodejs中exports和module.exports的区别
Feb 17 NodeJs
基于nodejs 的多页面爬虫实例代码
May 31 NodeJs
NodeJS链接MySql数据库的操作方法
Jun 27 NodeJs
使用nodeJs来安装less及编译less文件为css文件的方法
Nov 20 NodeJs
nodejs实现OAuth2.0授权服务认证
Dec 27 NodeJs
nodejs中用npm初始化来创建package.json的实例讲解
Oct 10 NodeJs
NodeJS http模块用法示例【创建web服务器/客户端】
Nov 05 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发送邮件类代码附详细说明
2008/07/10 PHP
php实现源代码加密的方法
2015/07/11 PHP
XMLHTTPRequest的属性和方法简介
2010/11/23 Javascript
js 关于=+与+=日期函数使用说明(赋值运算符)
2011/11/15 Javascript
如何让easyui gridview 宽度自适应窗口改变及fitColumns应用
2013/01/25 Javascript
jquery实现图片翻页效果
2013/12/23 Javascript
javascript中match函数的用法小结
2014/02/08 Javascript
extjs 分页使用jsp传递数据示例
2014/07/29 Javascript
javascript使用正则获取url上的某个参数
2014/09/04 Javascript
浅谈Javascript的静态属性和原型属性
2015/05/07 Javascript
使用impress.js制作幻灯片
2015/09/09 Javascript
[原创]JS基于FileSaver.js插件实现文件保存功能示例
2016/12/08 Javascript
利用BootStrap的Carousel.js实现轮播图动画效果
2016/12/21 Javascript
Javascript之深入浅出prototype
2017/02/06 Javascript
ES6学习笔记之map、set与数组、对象的对比
2018/03/01 Javascript
浅谈Fetch 数据交互方式
2018/12/20 Javascript
详解微信小程序-扫一扫 wx.scanCode() 扫码大变身
2019/04/30 Javascript
微信小程序把百度地图坐标转换成腾讯地图坐标过程详解
2019/07/10 Javascript
vue 自定义右键样式的实例代码
2019/11/06 Javascript
详解Vue中的Props与Data细微差别
2020/03/02 Javascript
[43:51]2018DOTA2亚洲邀请赛3月30日 小组赛B组 EG VS Secret
2018/03/31 DOTA
Python中列表与元组的乘法操作示例
2018/02/10 Python
使用TensorFlow实现简单线性回归模型
2019/07/19 Python
Python如何使用ElementTree解析xml
2020/10/12 Python
Python如何使用ConfigParser读取配置文件
2020/11/12 Python
Python字符串的15个基本操作(小结)
2021/02/03 Python
CSS3中几个新增加的盒模型属性使用教程
2016/03/01 HTML / CSS
使用索引(Index)有哪些需要考虑的因素
2016/10/19 面试题
2014旅游局领导班子四风问题对照检查材料思想汇报
2014/09/19 职场文书
学校党的群众路线教育实践活动总结材料
2014/10/30 职场文书
公务员个人考察材料
2014/12/23 职场文书
培训通知
2015/04/17 职场文书
2015年秋季学校开学标语
2015/07/16 职场文书
大学开学典礼新闻稿
2015/07/17 职场文书
python缺失值的解决方法总结
2021/06/09 Python
Elasticsearch 数据类型及管理
2022/04/19 Python