中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Node.js模塊查找,引用及緩存機制是什么

發布時間:2023-05-09 17:54:16 來源:億速云 閱讀:271 作者:iii 欄目:開發技術

這篇文章主要介紹“Node.js模塊查找,引用及緩存機制是什么”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Node.js模塊查找,引用及緩存機制是什么”文章能幫助大家解決問題。

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

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

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

    var mod = require('module_name')

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

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

    1. 載入內置模塊(A Core Module)

    2. 載入文件模塊(A File Module)

    3. 載入文件目錄模塊(A Folder Module)

    4. 載入node_modules里的模塊

    5. 自動緩存已載入模塊

    一、載入內置模塊

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

    var http = require('http')

    返回的http即是實現了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模塊查找,引用及緩存機制是什么

    package.json定義如下

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

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

    四、載入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)

    命令行執行:

    node init.js

    輸入如下

    Node.js模塊查找,引用及緩存機制是什么

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

    2. nodejs 模塊查找

    Node.js模塊查找,引用及緩存機制是什么

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

    查找順序:

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

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

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

    console.log(module.paths);

    我們將其放到任意一個目錄中執行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模塊查找,引用及緩存機制是什么

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

    1. 從module path數組中取出第一個目錄作為查找基準。

    2. 直接從目錄中查找該文件,如果存在,則結束查找。如果不存在,則進行下一條查找。

    3. 嘗試添加.js、.json、.node后綴后查找,如果存在文件,則結束查找。如果不存在,則進行下一條。

    4. 嘗試將require的參數作為一個包來進行查找,讀取目錄下的package.json文件,取得main參數指定的文件。

    5. 嘗試查找該文件,如果存在,則結束查找。如果不存在,則進行第3條查找。

    6. 如果繼續失敗,則取出module path數組中的下一個目錄作為基準查找,循環第1至5個步驟。

    7. 如果繼續失敗,循環第1至6個步驟,直到module path中的最后一個值。

    8. 如果仍然失敗,則拋出異常。

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

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

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

    Node.js模塊查找,引用及緩存機制是什么

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

    3. 利用nodejs模塊緩存機制創建“全局變量”

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

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

    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

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

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

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

    server.js中的片段:

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

    假定我們現在是這樣的:

    app.js的片段:

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

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

    app.app.close()

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

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

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

    這個時候怎么辦?

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

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

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

    關于“Node.js模塊查找,引用及緩存機制是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    呼玛县| 灵石县| 湖南省| 正蓝旗| 永城市| 社旗县| 宣城市| 颍上县| 五莲县| 庆云县| 永修县| 金湖县| 教育| 巩留县| 宜宾县| 攀枝花市| 常宁市| 阳城县| 德州市| 南宁市| 屯昌县| 安达市| 始兴县| 册亨县| 玛纳斯县| 平罗县| 洛浦县| 来宾市| 澄迈县| 南雄市| 周宁县| 石楼县| 澜沧| 梧州市| 廊坊市| 武强县| 揭阳市| 宿迁市| 斗六市| 邛崃市| 图木舒克市|