最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Node.js:模塊查找,引用及緩存機制詳解

 更新時間:2023年03月30日 08:24:36   作者:zhangying2001  
Node.js是一個基于Chrome?V8引擎的JavaScript運行環(huán)境,它的模塊查找、引用和緩存機制是其重要的特性之一。本文將介紹Node.js的模塊查找、引用和緩存機制,以及如何利用這些機制來提高應用程序的性能和可維護性。

1. Node.js的模塊載入方式與機制

Node.js中模塊可以通過文件路徑或名字獲取模塊的引用。模塊的引用會映射到一個js文件路徑,除非它是一個Node內置模塊。Node的內置模塊公開了一些常用的API給開發(fā)者,并且它們在Node進程開始的時候就預加載了。

其它的如通過NPM安裝的第三方模塊(third-party modules)或本地模塊(local modules),每個模塊都會暴露一個公開的API。以便開發(fā)者可以導入。如

var mod = require('module_name')

此句執(zhí)行后,Node內部會載入內置模塊或通過NPM安裝的模塊。require函數(shù)會返回一個對象,該對象公開的API可能是函數(shù),對象,或者屬性如函數(shù),數(shù)組,甚至任意類型的JS對象。

這里列下node模塊的載入及緩存機制

  1. 載入內置模塊(A Core Module)
  2. 載入文件模塊(A File Module)
  3. 載入文件目錄模塊(A Folder Module)
  4. 載入node_modules里的模塊
  5. 自動緩存已載入模塊

一、載入內置模塊

Node的內置模塊被編譯為二進制形式,引用時直接使用名字而非文件路徑。當?shù)谌降哪K和內置模塊同名時,內置模塊將覆蓋第三方同名模塊。因此命名時需要注意不要和內置模塊同名。如獲取一個http模塊

var http = require('http')

返回的http即是實現(xiàn)了HTTP功能Node的內置模塊。

二、載入文件模塊

絕對路徑的

var myMod = require('/home/base/my_mod')

或相對路徑的

var myMod = require('./my_mod')

注意,這里忽略了擴展名“.js”,以下是對等的

var myMod = require('./my_mod') 
var myMod = require('./my_mod.js')

三、載入文件目錄模塊

可以直接require一個目錄,假設有一個目錄名為folder,如

var myMod = require('./folder')

此 時,Node將搜索整個folder目錄,Node會假設folder為一個包并試圖找到包定義文件package.json。如果folder 目錄里沒有包含package.json文件,Node會假設默認主文件為index.js,即會加載index.js。如果index.js也不存在, 那么加載將失敗。

假如目錄結構如下

Node.js:模塊查找,引用及緩存機制_操作系統(tǒng)

package.json定義如下

{
    "name": "pack",
    "main": "modA.js"
}

此時 require('./folder') 將返回模塊modA.js。如果package.json不存在,那么將返回模塊index.js。如果index.js也不存在,那么將發(fā)生載入異常。

四、載入node_modules里的模塊

如果模塊名不是路徑,也不是內置模塊,Node將試圖去當前目錄的node_modules文件夾里搜索。如果當前目錄的node_modules里沒有找到,Node會從父目錄的node_modules里搜索,這樣遞歸下去直到根目錄。

不必擔心,npm命令可讓我們很方便的去安裝,卸載,更新node_modules目錄。

五、自動緩存已載入模塊

對于已加載的模塊Node會緩存下來,而不必每次都重新搜索。下面是一個示例

modA.js

console.log('模塊modA開始加載...') 
exports = function() { 
    console.log('Hi') 
} 
console.log('模塊modA加載完畢')

init.js

var mod1 = require('./modA') 
var mod2 = require('./modA') 
console.log(mod1 === mod2)

命令行執(zhí)行:

node init.js

輸入如下

Node.js:模塊查找,引用及緩存機制_json_02

可以看到雖然require了兩次,但modA.js仍然只執(zhí)行了一次。mod1和mod2是相同的,即兩個引用都指向了同一個模塊對象。

2. nodejs 模塊查找

Node.js:模塊查找,引用及緩存機制_ViewUI_03

nodejs在加載外部自定義模塊時對模塊有查找順序,找到后還會進行緩存。

查找順序:

1. 相對路徑,比如提供./ 或者../這種以'./'和‘..’開始的路徑,簡單的,就是相對當前位置的路徑。

2.絕對路徑,這時候將按以下順序查找:

在 進入路徑查找之前有必要描述一下module path這個Node.js中的概念。對于每一個被加載的文件模塊,創(chuàng)建這個模塊對象的時候,這個模塊便會有一個paths屬性,其值根據當前文件的路徑 計算得到。我們創(chuàng)建modulepath.js這樣一個文件,其內容為:

console.log(module.paths);

我們將其放到任意一個目錄中執(zhí)行node modulepath.js命令,將得到以下的輸出結果。

[ '/home/ikeepstudying/research/node_modules',
'/home/ikeepstudying/node_modules',
'/home/node_modules',
'/node_modules' ]

Windows下:

[ 'c:\\nodejs\\node_modules', 'c:\\node_modules' ]

然后是['.']

然后是:

windows下%NODE_PATH%,%USERPROFILE%/.node_modules, %USERPROFILE%/.node_libraries

非windows下$NODE_PATH, $HOME/.node_modules, $HOME/.node_libraries

[NODE_PATH,HOME/.node_modules,HOME/.node_libraries,execPath/../../lib/node]

然后是node.exe目錄的../../lib/node,所以這個具體取決于node二進制文件放哪里.

Node.js:模塊查找,引用及緩存機制_ViewUI_04

簡而言之,如果require絕對路徑的文件,查找時不會去遍歷每一個node_modules目錄,其速度最快。其余流程如下:

  1. 從module path數(shù)組中取出第一個目錄作為查找基準。
  2. 直接從目錄中查找該文件,如果存在,則結束查找。如果不存在,則進行下一條查找。
  3. 嘗試添加.js、.json、.node后綴后查找,如果存在文件,則結束查找。如果不存在,則進行下一條。
  4. 嘗試將require的參數(shù)作為一個包來進行查找,讀取目錄下的package.json文件,取得main參數(shù)指定的文件。
  5. 嘗試查找該文件,如果存在,則結束查找。如果不存在,則進行第3條查找。
  6. 如果繼續(xù)失敗,則取出module path數(shù)組中的下一個目錄作為基準查找,循環(huán)第1至5個步驟。
  7. 如果繼續(xù)失敗,循環(huán)第1至6個步驟,直到module path中的最后一個值。
  8. 如果仍然失敗,則拋出異常。

整個查找過程十分類似原型鏈的查找和作用域的查找。所幸Node.js對路徑查找實現(xiàn)了緩存機制,否則由于每次判斷路徑都是同步阻塞式進行,會導致嚴重的性能消耗。

一旦加載成功就以模塊的路徑進行緩存,這里有一個陷阱。

就是如果父目錄包含X模塊,且存在引用X模塊的代碼。而子目錄也是相同的情況。那么父目錄和子目錄下實際引用到的分別是自己目錄下的那個X模塊,而不是之前那個的復用。也就是要注意他緩存是匹配全路徑的。

Node.js:模塊查找,引用及緩存機制_加載_05

Nodejs:模塊查找,引用及緩存機制

3. 利用nodejs模塊緩存機制創(chuàng)建“全局變量”

在《深入淺出nodejs》有這樣一段(有部分增減):

nodejs引入模塊分四個步驟 路徑分析 文件定位 編譯執(zhí)行 加入內存 核心模塊部分在node源代碼的編譯過程中就編譯成了二級制文件,在node啟動時就直接加載如內存,所以這部分模塊引入時,前三步省略,直接加入。 nodejs的模塊加載和瀏覽器js加載一樣都有緩存機制,不同的是,瀏覽器僅僅緩存文件,而nodejs緩存的是編譯和執(zhí)行后的對象(緩存內存)。 基于以上三點:我們可以編寫一個模塊,用來記錄長期存在的變量。例如:我可以編寫一個記錄接口訪問數(shù)的模塊:

var count = {}; // 因模塊是封閉的,這里實際上借用了js閉包的概念
exports.count = function(name){ 
    if(count[name]){ 
        count[name]++; 
    }else{ 
        count[name] = 1; 
    } 
    console.log(name + '被訪問了' + count[name] + '次。'); 
};

我們在路由里這樣引用:

var count = require('count');
export.index = function(req, res){
    count('index');
};

4. nodejs清除require緩存 delete require.cache

開發(fā)nodejs應用時會面臨一個麻煩的事情,就是修改了配置數(shù)據之后,必須重啟服務器才能看到修改后的結果。

于是問題來了,挖掘機哪家強?噢,no! no! no!

怎么做到修改文件之后,自動重啟服務器。

server.js中的片段:

var port = process.env.port || 1337;app.listen(port);
console.log("server start in " + port);
exports.app = app;

假定我們現(xiàn)在是這樣的:

app.js的片段:

var app = require('./server.js');

如果我們在server.js中啟動了服務器,我們停止服務器可以在app.js中調用

app.app.close()

但是當我們重新引入server.js

app = require('./server.js')

的時候會發(fā)現(xiàn)并不是用的最新的server.js文件,原因是require的緩存機制,在第一次調用require('./server.js')的時候緩存下來了。

這個時候怎么辦?

下面的代碼解決了這個問題:

delete require.cache[require.resolve('./server.js')];
app = require('./server.js');

Node.js的模塊查找、引用和緩存機制是其獨特的特性之一,它們?yōu)殚_發(fā)人員提供了更好的性能和可維護性。了解這些機制的工作原理和使用方法,可以幫助開發(fā)人員更好地利用Node.js的優(yōu)勢,提高應用程序的性能和可維護性。

到此這篇關于Node.js:模塊查找,引用及緩存機制詳解的文章就介紹到這了,更多相關Node.js模塊查找,引用及緩存機制內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關文章

  • nodejs實現(xiàn)發(fā)出蜂鳴聲音(系統(tǒng)報警聲)的方法

    nodejs實現(xiàn)發(fā)出蜂鳴聲音(系統(tǒng)報警聲)的方法

    這篇文章主要介紹了nodejs實現(xiàn)發(fā)出蜂鳴聲音(系統(tǒng)報警聲)的方法,結合實例形式分析了nodejs發(fā)出蜂鳴聲的原理及具體應用方法,需要的朋友可以參考下
    2017-01-01
  • Nodejs使用SQL模糊查詢的過程詳解

    Nodejs使用SQL模糊查詢的過程詳解

    最近在改一個比較久的項目,是使用nodejs寫的,但是對于長期寫java的后端開發(fā)來說,還是有點難維護,不過不改bug的話,就需要重新開發(fā),所以本文介紹了NodeJs如何使用SQL模糊查詢,需要的朋友可以參考下
    2024-07-07
  • Ubuntu 16.04 64位中搭建Node.js開發(fā)環(huán)境教程

    Ubuntu 16.04 64位中搭建Node.js開發(fā)環(huán)境教程

    如果想要在Ubuntu 16.04上安裝Node.js的話,這篇文章對你來說肯定很重要。Node.js從本質上來說就是一個運行在服務端上的封裝好了輸入輸出流的javascript程序。本文給大家詳細介紹了在Ubuntu 16.04 64位搭建Node.js開發(fā)環(huán)境的步驟,有需要的朋友們可以參考學習。
    2016-10-10
  • node.js 如何監(jiān)視文件變化

    node.js 如何監(jiān)視文件變化

    這篇文章主要介紹了node.js 如何監(jiān)視文件變化,幫助大家更好的理解和學習node.js,感興趣的朋友可以了解下
    2020-09-09
  • Node使用Puppeteer監(jiān)聽并打印網頁的接口請求

    Node使用Puppeteer監(jiān)聽并打印網頁的接口請求

    Puppeteer 是一個 Node 庫,它提供了高級的 API 來通過 DevTools 協(xié)議控制 Chrome 或 Chromium,本文我們就來看看如何使用Puppeteer監(jiān)聽并打印網頁的接口請求吧
    2025-04-04
  • Nest.js中使用HTTP五種數(shù)據傳輸方式小結

    Nest.js中使用HTTP五種數(shù)據傳輸方式小結

    本文主要介紹了Nest.js中使用HTTP五種數(shù)據傳輸方式小結,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-05-05
  • Nodejs訪問網絡并解析返回的json的實現(xiàn)方法

    Nodejs訪問網絡并解析返回的json的實現(xiàn)方法

    本文主要介紹了Nodejs訪問網絡并解析返回的json的實現(xiàn)方法,文中根據實例編碼詳細介紹的十分詳盡,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • pnpm workspace管理monorepo項目使用過程詳解

    pnpm workspace管理monorepo項目使用過程詳解

    這篇文章主要為大家介紹了pnpm workspace管理monorepo項目使用過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10
  • 升級Node.js版本的超詳細指南

    升級Node.js版本的超詳細指南

    Node.js是一個開源、跨平臺的JavaScript運行時環(huán)境,廣泛應用于服務器端和網絡應用的開發(fā),下面這篇文章主要介紹了升級Node.js版本的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2025-10-10
  • 如何使用nexus3搭建npm私有倉庫

    如何使用nexus3搭建npm私有倉庫

    這篇文章主要介紹了如何使用nexus3搭建npm私有倉庫,包括安裝并運行私服的相關知識,本文結合實例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-03-03

最新評論

罗定市| 仁布县| 澎湖县| 东阳市| 濮阳市| 达日县| 岳阳市| 扎赉特旗| 色达县| 定襄县| 英超| 连州市| 五大连池市| 田东县| 龙胜| 南昌县| 卫辉市| 雷山县| 石景山区| 宜兰市| 邯郸县| 茶陵县| 泗水县| 康平县| 漠河县| 金寨县| 淮阳县| 博湖县| 五家渠市| 全南县| 洞头县| 胶州市| 阳原县| 金寨县| 叙永县| 新乡市| 江源县| 体育| 比如县| 晋江市| 贡嘎县|