前言

使用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的生成过程。

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

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

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()函数便会被引入。下面我们分析一下这个函数:

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

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

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

native 优先级最低

2.应用启动的过程

上图为一个流程图,它描述了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的运行原理-模块篇的更多相关文章

  1. 【原创】分布式之数据库和缓存双写一致性方案解析(三) 前端面试送命题(二)-callback,promise,generator,async-await JS的进阶技巧 前端面试送命题(一)-JS三座大山 Nodejs的运行原理-科普篇 优化设计提高sql类数据库的性能 简单理解token机制

    [原创]分布式之数据库和缓存双写一致性方案解析(三)   正文 博主本来觉得,<分布式之数据库和缓存双写一致性方案解析>,一文已经十分清晰.然而这一两天,有人在微信上私聊我,觉得应该要采用 ...

  2. Nodejs的运行原理-架构篇

    前言 本来是想只做一个Nodejs运行原理-科普篇,但是收到了不少私信,要我多分享一些更进阶,更详细的内容,所以我会在接下来的两个月里继续更新Nodejs运行原理. PS:此系列只做Nodejs的运行 ...

  3. Nodejs的运行原理-libuv篇

    前言 这应该是Nodejs的运行原理的第7篇分享,这篇过后,短时间内不会再分享Nodejs的运行原理,会停更一段时间,PS:不是不更,而是会开挖新的坑,最近有在研究RPG Maker MV,区块链,云 ...

  4. Nodejs的运行原理-调用篇

    前言 之前做过Nodejs的架构篇, 有很多朋友留言给我,说没看懂里面的例子,这里我会重新梳理一下,再以http server为例,来解析Nodejs从前端到libuv的调用过程. 正文 回忆a. N ...

  5. Nodejs的运行原理-科普篇

    前言 Nodejs目前处境稍显尴尬,很多语言都已经拥有异步非阻塞的能力.阿里的思路是比较合适的,但是必须要注意,绝对不能让node做太多的业务逻辑,他只适合接收生成好的数据,然后或渲染后,或直接发送到 ...

  6. Nodejs的运行原理-生态篇

    前言 这里是重点:Nodejs 是由v8 engine,libuv和内置模块组成,可以将v8 engine和 libuv看成一个库,两者是以源码的方式直接编译执行node中去的. 这是一个广泛的介绍, ...

  7. Nodejs的运行原理-函数回调篇

    前言 当客户端向http server 发起TCP链接时,server端会发起一系列的callback调用,这是一个逆向调用的过程:开始于libuv,终止于js代码里的callback(promise ...

  8. 谈谈 Python 程序的运行原理

    因为我的个人网站 restran.net 已经启用,博客园的内容已经不再更新.请访问我的个人网站获取这篇文章的最新内容,谈谈 Python 程序的运行原理 这篇文章准确说是『Python 源码剖析』的 ...

  9. NodeJS学习笔记 进阶 (12)Nodejs进阶:crypto模块之理论篇

    个人总结:读完这篇文章需要30分钟,这篇文章讲解了使用Node处理加密算法的基础. 摘选自网络 Nodejs进阶:crypto模块之理论篇 一. 文章概述 互联网时代,网络上的数据量每天都在以惊人的速 ...

随机推荐

  1. SDP(1):ScalikeJDBC-基本操作介绍

    简单来说:JDBC是一种开放标准的跨编程语言.跨数据库类型编程API.各类型数据库产品厂商都会按它的标准要求来提供针对自身产品的JDBC驱动程序.最主要的这是一套成熟的工具,在编程人员中使用很普及.既 ...

  2. 把要写的内容做个list,半年过去了

    先说点题外话,来国家气象局的第三周,今天出去和丁书记吃了个饭,基本在聊大学时候的人和事,好像都没怎么变,只是不联系的人愈发不会再联系. 抛开学校的课程不谈,半年做了三件事:CUMT校园导航 / Ope ...

  3. Java中的对象Object方法之---wait()和notifiy()

    这一篇咋们继续,接着来介绍wait()和notify()方法,我们都知道这两个方法和之前介绍的方法不太一样,那就是这两个方法是对象Object上的,不属于Thread类上的.我们也知道这两个方法是实现 ...

  4. python与MySQL

    一.python与mysql交互 因版本不同python操作mysql有两个模块,python3不再支持MySQL-python,模块使用都一样: python2.7:MySQL-python pyt ...

  5. K8S API 调用

    不好意,本人比较懒,OneNote 复制粘贴的时候就是自动变成图片了.请各位看官多多见谅. 遗留问题: 目前pod仅支持修改 * and(),so...

  6. logback使用配置详解

    title: logback使用配置详解 date: 2017-04-25 16:42:49 tags: 日志 --- 1.介绍 Logback是由log4j创始人设计的另一个开源日志组件,它当前分为 ...

  7. Linxu指令--date,cal

    在linux环境中,不管是编程还是其他维护,时间是必不可少的,也经常会用到时间的运算,熟练运用date命令来表示自己想要表示的时间,肯定可以给自己的工作带来诸多方便. 1.命令格式: date [参数 ...

  8. 无废话XML--XML约束(DTD)

    基本术语     一.序言Prolog:包括XML声明(XML Declaration)和文档类型声明(Document Type Declaration).     二.良构(well-formed ...

  9. 自己用的一套reset.css,打算整理一下方便以后用,持续更新中,各位大神,不喜勿喷

    *{margin: 0; padding: 0;border:none;}img{vertical-align: top;width: 100%;border: none;}ul,li{list-st ...

  10. Android更新主线程UI的两种方式handler与runOnUiThread()

    在android开发过程中,耗时操作我们会放在子线程中去执行,而更新UI是要主线程(也叫做:UI线程)来更新的,自然会遇到如何更新主线程UI的问题.如果在主线程之外的线程中直接更新页面显示常会报错.抛 ...