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模塊的載入及緩存機制
載入內置模塊(A Core Module)
載入文件模塊(A File Module)
載入文件目錄模塊(A Folder Module)
載入node_modules里的模塊
自動緩存已載入模塊
一、載入內置模塊
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也不存在,那么加載將失敗媳搪。
假如目錄結構如下
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
輸入如下
可以看到雖然require了兩次,但modA.js仍然只執(zhí)行了一次直晨。mod1和mod2是相同的搀军,即兩個引用都指向了同一個模塊對象。