node.js模塊
在node.js開發中一個文件就可以認為是一個模塊。
一、node.js模塊分類
核心模塊Code Module、內置模塊、原生模塊
fs
http
path
url
...
所有內置模塊在安裝node.js的時候就已經編譯成二進制文件,可以直接加載運行(速讀較快)
部分內置模塊,在node.exe這個進程啟動的時候就已經默認加載了,所以可以直接使用。
文件模塊
按文件后綴來分
如果加載時,沒有指定后綴名,那么就按照如下順序依次加載相應模塊
1.js
2.json
4.node(C/c++編寫模塊)
自定義模塊
mime
cheerio
moment
mongo
...
二、加載順序
1.require(一個路徑)
require('./index2') //index2.js //index2.json //index2.node //index2文件夾->package.json文件->main(入口文件 app.js->index.js/index.json/index.node)->加載失敗
在加載index2的時候,require會先去找index2.js文件,沒有就去找.json文件,再沒有就找node文件,如果這些都沒有,它會認為index2是一個文件夾,如果找到了這個文件夾,require還會去找這個文件夾里面是否有package.json,如果沒有就加載失敗,如果有,就找package.json里的main(),就加載里面的index.js/index.json/index.node,如果沒有,也是失敗。
在加載文件模塊的時候最好寫上后綴,這樣會省一些步驟
2.require()的參數不是一個路徑,直接是一個模塊名稱
1).現在核心模塊中查找,是否有名字一樣的模塊,如果有,則直接加載該核心模塊
如:require('http')
2)如果核心模塊中沒有該模塊,就很認為是一個第三方模塊(自定義模塊)
先會去當前js文件所在的目錄下找node_modules文件夾,當前目錄沒有,會去當前執行的文件的父目錄里面尋找
三、require加載注意事項
1.所以模塊第一次加載完畢以后都會有緩存,第二次加載直接讀取緩存,避免了二次開銷
因為有緩存,所以模塊中的代碼只在第一次加載的時候執行一次
2.每次加載模塊的時候都有限從緩存中加載,緩存中沒有才會按照node.js加載模塊規則去查找
3.核心模塊Node.js源碼編譯的時候,都已經編譯為二進制執行文件,所以加載速度較快(核心模塊加載優先級僅次於緩存加載)
4.試圖加載一個和核心模塊同名的自定義(第三方模塊)是不會成功的
自定義模塊要么名字不要和核心模塊同名,要么使用路徑的方式加載
6.核心模塊只能通過模塊名稱來加載
7.require()加載模塊使用./相對路徑時,是先對當前模塊,不受node命令執行路徑影響
8.建議在加載文件模塊時,盡量添加文件后綴名
四、require加載原理
在a.js文件中
//加載b.js模塊 require('./b.js');
在b.js文件中
function add(x,y){ return x+y; } var result=add(100,1000); console.log(result);
執行a.js
加載自定義模塊b.js的時候,會執行一次b.js
修改a.js
//加載b.js模塊 require('./b.js'); require('./b.js'); require('./b.js'); require('./b.js'); require('./b.js'); require('./b.js');
執行a.js
由此可見,require模塊第一次加載會執行模塊代碼,后面加載的模塊都是從緩存里面獲取的,所以不會再去執行模塊代碼了。
在文件中查找第三方模塊時依次查找的路徑
console.log(module.paths);
源代碼
1.檢查Module.cache里有沒有緩存的模塊實例,如果緩存里面沒有,就創建一個Module實例,將創建的Module保存到緩存里面,供下次使用
2.調用module.load()讀取模塊內容,然后調用modele.compile()編譯執行(封裝為一個沙盒)改模塊
3.如果加載出錯,就從緩存中刪除該模塊
4.返回module.export
主要做的是通過module._load來加載模塊,判斷緩存,如果沒在緩存里就創建