溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Nodejs模塊載入運(yùn)行原理

發(fā)布時(shí)間:2020-08-24 01:36:28 來(lái)源:腳本之家 閱讀:379 作者:peiyu1988 欄目:web開(kāi)發(fā)

前言

使用Nodejs,就不可避免地引用第三方模塊,它們有些是Nodejs自帶的(例:http,net...),有些是發(fā)布在npm上的(例:mssql,elasticsearch...)

本篇章聚焦3個(gè)問(wèn)題:

  1. Nodejs模塊的加載過(guò)程。
  2. 應(yīng)用啟動(dòng)的過(guò)程。
  3. 應(yīng)用如何加載依賴(lài)模塊。

1.模塊的加載過(guò)程

Nodejs 模塊大概可分為4種:

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

b) constant module Nodejs中定義常量的模塊。

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

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

我們先看builtin module 和 native module的生成過(guò)程。

Nodejs模塊載入運(yùn)行原理

native JS module的生成相對(duì)復(fù)雜一些,編譯后,會(huì)在/out/release/obj/gen目錄下生成一個(gè)node_natives.h。

該文件是由js2c.py生成,它會(huì)把Nodejs源碼中的lib目錄下,所有js文件轉(zhuǎn)成ASCII碼,并存放在相應(yīng)的數(shù)組里。

Nodejs模塊載入運(yùn)行原理

builtin C++ module 生成過(guò)程相對(duì)簡(jiǎn)單,每個(gè)builtin C++的模塊入口,都會(huì)通過(guò)宏NODE_MODULE_CONTEXT_AWARE_BUILTIN擴(kuò)展成一個(gè)func,例如對(duì)tcp_wrap模塊而言,會(huì)擴(kuò)展成static void register_tcp_wrap() attribute(constructor) 函數(shù)。

熟悉GCC的朋友都知道,attribute(constructor)修飾的函數(shù)會(huì)在Nodejs的main()函數(shù)之前被執(zhí)行,也就是說(shuō),builtin C++ module 會(huì)在main()函數(shù)之前被載入到modlist_builtin列表,而modlist_builtin是一個(gè)struct node_module類(lèi)型的指針,get_builtin_module()會(huì)遍歷查找我們所需的模塊。

其實(shí)無(wú)論是naive JS module 還是 builtin C++ module,最終都是要被編譯成可執(zhí)行文件。對(duì)于兩者的提取方式,卻大不相同,js module 使用process.binding('natives'),而C++ module 則直接使用get_builtin_module()。

在node.cc里面提供了一個(gè)binding()函數(shù),當(dāng)我們應(yīng)用require()來(lái)引用另外一個(gè)模塊時(shí),binding()函數(shù)便會(huì)被引入。下面我們分析一下這個(gè)函數(shù):

Nodejs模塊載入運(yùn)行原理

可以目測(cè)到,函數(shù)主要為三個(gè)模塊服務(wù):builtin,constants和native。

builtin優(yōu)先級(jí)最高,會(huì)到modlist_builtin中查找,過(guò)程非常簡(jiǎn)單,遍歷整個(gè)列表,查找相同名字的模塊即可。找到后,模塊的注冊(cè)函數(shù)會(huì)被先執(zhí)行,然后將數(shù)據(jù)exports返回。

constants模塊優(yōu)先級(jí)次之,Nodejs中的常量定義通過(guò)constants導(dǎo)出。

native 優(yōu)先級(jí)最低。

2.應(yīng)用啟動(dòng)的過(guò)程

Nodejs模塊載入運(yùn)行原理

上圖為一個(gè)流程圖,它描述了test.js做為參數(shù)啟動(dòng)開(kāi)始,最終被執(zhí)行。整個(gè)過(guò)程可以分為4步:

1.可執(zhí)行文件 node : node入口,在啟動(dòng)過(guò)程中主要扮演環(huán)境準(zhǔn)備工作

2.src/node.js:?jiǎn)?dòng)腳本

3.Native Module:為module.js 的執(zhí)行做準(zhǔn)備工作

4.module.js:native module,用來(lái)加載,編譯,執(zhí)行應(yīng)用程序

應(yīng)用如何加載依賴(lài)模塊

前面提到NativeModule.require()只負(fù)責(zé)幫助引用natives module,這對(duì)于lib/module.js而言已經(jīng)足夠了。

但是很明顯,一般應(yīng)用不但需要引用matives module,還要引用第三方模塊,讓我們看一下module.js中的Module.prototype._require()函數(shù)中。

Nodejs模塊載入運(yùn)行原理

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI