nodejs中 require 方法的載入規則

2021-09-20 18:41:15 字數 3805 閱讀 5509

(function (exports, require, module, __filename, __dirname) );
console.log(module.paths);
[ '/home/jackson/research/node_modules', 

'/home/jackson/node_modules',

'/home/node_modules',

'/node_modules' ]

windows下:

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

'c:\\node_modules' ]

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

除此之外還有乙個全域性module path,是當前node執行檔案的相對目錄(../../lib/node)。如果在環境變數中設定了home目錄和node_path目錄的話,整個路徑還包含node_path和home目錄下的.node_libraries與.node_modules。其最終值大致如下:

[node_path,home/.node_modules,home/.node_libraries,execpath/../../lib/node]
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 中存在 4 類模組(原生模組和3種檔案模組),儘管 require 方法極其簡單,但是內部的載入卻是十分複雜的,其載入優先順序也各自不同。如下圖所示:

一、優先從檔案模組快取中載入

儘管原生模組與檔案模組的優先順序不同,但是都會優先從檔案模組的快取中載入已經存在的模組。

二、原生模組

原生模組的優先順序僅次於檔案模組快取的優先順序。require 方法在解析檔名之後,優先檢查模組是否在原生模組列表中。

在實際開發過程中,如果你的檔案和核心庫檔案同名,載入過程中是會直接忽略你的專案檔案。

例如在server下有config.json,require("config")。

require具體的載入過程是:

(1)核心庫中如果有config.js 會直接載入 忽略你的檔案。

(2)如果沒有會檢查你的專案中是否有這個.js檔案。

(3)如果沒有才會去查詢 .json 檔案。

所以在開發過程中最好使用其相對路徑指明具體檔案。

當第三方的模組和內建模組同名時,內建模組將覆蓋第三方同名模組。因此命名時需要注意不要和內建模組同名。

原生模組也有乙個快取區,同樣也是優先從快取區載入。如果快取區沒有被載入過,則呼叫原生模組的載入方式進行載入和執行。

原生模組的本質也是檔案,原生模組檔案已經被編譯到了二進位制檔案中了,我們只需要按照名字來載入就可以了。如:

三、路徑形式的模組

我們說的路徑形式的模組,其實就是載入自己寫的js檔案,有四種方式可以載入

當檔案模組快取中不存在,而且不是原生模組的時候,node.js 會解析 require 方法傳入的引數,並從檔案系統中載入實際的檔案 。

var fooexports = require('./index')	//相對路徑,常用

var fooexports = require('../index') //相對路徑,常用

var fooexports = require('/index') //根目錄,不常用

var fooexports = require('d:/demo/index') //根目錄,不常用

注意,這裡忽略了副檔名「.js」,以下是對等的:

var mymod = require('./my_mod')

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

如果當前目錄有my_mod.js和my_mod.json,則會優先載入 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也不存在, 那麼載入將失敗。 

假如目錄結構如下:

package.json定義如下:

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

如果foder同級目錄還有folder.js和folder.json,同時folder目錄下還有index.js,則require('./folder') 將返回folder.js中的內容,否則返回folder.json中的內容,否則會返回folder目錄下index.js中的內容,最後才會返回moda.js中的內容。

四、第三方模組

使用的時候就可以通過 require(『包名』) 的方式來進行載入才可以使用;

不可能有任何乙個第三方包和核心模組的名字是一樣的。

既不是核心模組、也不是路徑形式的模組,就是第三方模組。

如果模組名不是路徑,也不是內建模組,node將試圖去當前目錄的node_modules資料夾裡搜尋。如果當前目錄的node_modules裡沒有找到,node會從父目錄的node_modules裡搜尋,這樣遞迴下去直到根目錄。

總結:

其實主要就是兩種情況:

1、如果require中是名稱,則說明搜尋的是內建模組或者第三方模組,此時內建模組的優先順序高於第三方模組;

2、如果require中是路徑,則會按照自定義模組的規則查詢。

nodejs的require模組及路徑

在nodejs中,模組大概可以分為核心模組和檔案模組。核心模組是被編譯成二進位制 引用的時候只需require表示符即可,如 require net 檔案模組,則是指js檔案 json檔案或者是.node檔案。在引用檔案模組的時候後要加上檔案的路徑 js表示絕對路徑 js表示相對路徑 同一資料夾下的...

舉例講解Ruby中require的使用方法

同一目錄下的檔案,如 usr local ruby foo.rb與 usr local ruby bar.rb兩個檔案。如果直接在foo.rb中 require bar 執行時會報找不到bar.rb錯誤。這是因為執行 hwww.cppcns.comome oldsong ruby usr local...

lua中的require機制

lua中的require機制 2008 06 05 09 13 27 分類 python ruby lua中的require機制 為了方便 管理,通常會把lua 分成不同的模組,然後在通過require函式把它們載入進來。現在看看lua的require的處理流程。1 require機制相關的資料和函...