Node文件查找優先級以及Require方法的文件查找策略

模塊規范

NodejsCommonJS進行支持和實現,讓我們在開發Node的過程中科院方便的進行模塊化開發

  • Node中每一個js文件都是一個單獨的模塊
  • 模塊中包括CommonJs規范的核心變量:exportsmodule.exports,require
  • 通過上述變量進行模塊化開發

而模塊化的核心是導出與導入,在Node中通過exportsmodule.exports負責對模塊中的內容進行導出,通過require函數導入其他模塊(自定義模塊,系統模塊,第三方模塊)中的內容

查找策略

require 方法接收以下幾種參數的傳遞:

  • 原生模塊: http,fs,path等
  • 相對路徑文件模塊:./mod或../mod
  • 絕對路徑的文件模塊: /pathtomodule/mod
  • 目錄作為模塊: ./dirname
  • 非原生模塊的文件模塊: mod
    require 參數較為簡單,但是內部的加載卻十分復雜,其加載優先級也各自不同

    從上圖可以看見,文件模塊存在緩存區,尋找模塊路徑的時候都會優先從緩存中加載已經存在的模塊
原生模塊

如果require絕對路徑的文件,則直接查找對應的路徑,速度最快
相對路徑的模塊則相對于當前調用require的文件去查找
如果按確切的文件名沒有找到模塊,則Nodejs會嘗試帶上.js,.json.node擴展名再加載

目錄作為模塊

默認情況是根據目錄中的pakage.json文件的main來指定目錄模塊,如:

{
   "name":"some-library",
   "main":"main.js"
}

如果這是在./some-library node_modules目錄中,則 require('./some-library') 會試圖加載 ./some-library/main.js

如果目錄里沒有 package.json文件,或者 main入口不存在或無法解析,則會試圖加載目錄下的 index.jsindex.node 文件

非原生模塊

在每個文件中都存在module.paths,表示模塊的搜索路徑,require就是根據其來尋找文件

在window下輸出如下:

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

可以看出module path的生成規則為:從當前文件目錄開始查找node_modules目錄;然后依次進入父目錄,查找父目錄下的node_modules目錄,依次迭代,直到根目錄下的node_modules目錄

當都找不到的時候,則會從系統NODE_PATH環境變量查找

舉個例子:

如果在/home/ry/projects/foo.js文件里調用了 require('bar.js'),則 Node.js 會按以下順序查找:

  • /home/ry/projects/node_modules/bar.js
  • /home/ry/node_modules/bar.js
  • /home/node_modules/bar.js
  • /node_modules/bar.js

這使得程序本地化它們的依賴,避免它們產生沖突

總結

通過上面模塊的文件查找策略之后,總結下文件查找的優先級:

  • 緩存的模塊優先級最高

  • 如果是內置模塊,則直接返回,優先級僅次緩存的模塊

  • 如果是絕對路徑 / 開頭,則從根目錄找

  • 如果是相對路徑 ./開頭,則從當前require文件相對位置找

  • 如果文件沒有攜帶后綴,先從js、json、node按順序查找

  • 如果是目錄,則根據 package.json的main屬性值決定目錄下入口文件,默認情況為 index.js

  • 如果文件為第三方模塊,則會引入 node_modules 文件,如果不在當前倉庫文件中,則自動從上級遞歸查找,直到根目錄

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容