Node.js的模組載入方式與機制簡單介紹

admin發表於2017-03-24

Node.js中模組可以通過檔案路徑或名字獲取模組的引用。模組的引用會對映到一個js檔案路徑,除非它是一個Node內建模組。Node的內建模組公開了一些常用的API給開發者,並且它們在Node程式開始的時候就預載入了。Node.js中模組可以通過檔案路徑或名字獲取模組的引用。模組的引用會對映到一個js檔案路徑,除非它是一個Node內建模組。Node的內建模組公開了一些常用的API給開發者,並且它們在Node程式開始的時候就預載入了。

例如:

[JavaScript] 純文字檢視 複製程式碼
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模組,例如:

[JavaScript] 純文字檢視 複製程式碼
var http = require('http')

返回的http即是實現了HTTP功能Node的內建模組。

二.載入檔案模組:

絕對路徑的

[JavaScript] 純文字檢視 複製程式碼
var myMod = require('/home/base/my_mod')

或相對路徑的

[JavaScript] 純文字檢視 複製程式碼
var myMod = require('./my_mod')

注意,這裡忽略了副檔名“.js”,以下是對等的

[JavaScript] 純文字檢視 複製程式碼
var myMod = require('./my_mod')
var myMod = require('./my_mod.js')

三.載入檔案目錄模組:

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

[JavaScript] 純文字檢視 複製程式碼
var myMod = require('./folder')

此時,Node將搜尋整個folder目錄,Node會假設folder為一個包並試圖找到包定義檔案package.json。如果folder目錄裡沒有包含package.json檔案,Node會假設預設主檔案為index.js,即會載入index.js。如果index.js也不存在,那麼載入將失敗。

假如目錄結構如下:

a:3:{s:3:\"pic\";s:43:\"portal/201703/24/145745tof68ff6s4v4rfa6.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

package.json定義如下:

[JavaScript] 純文字檢視 複製程式碼
{
"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

[JavaScript] 純文字檢視 複製程式碼
console.log('模組modA開始載入...')
exports = function() {
console.log('Hi')
}
console.log('模組modA載入完畢')

init.js

[JavaScript] 純文字檢視 複製程式碼
var mod1 = require('./modA')
var mod2 = require('./modA')
console.log(mod1 === mod2)

命令列執行:

node init.js 

輸入如下

a:3:{s:3:\"pic\";s:43:\"portal/201703/24/145929k86vkqxztkjvjvwe.png\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

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

相關文章