0014 NodeJS的require
一.簡介
我們現在開發業務邏輯,經常性的依賴其他模塊。
在ES6之前(即在 CommonJS 中),沒有“模塊”,所以為了實現“模塊”效果而誕生了 require 用於加載模塊,對於暴露模塊有 module.exports 和 exports 兩種方式。
在NodeJS中,一個文件就是一個單獨的模塊。CommonJS規範規定,每個模塊內部,module變量代表當前模塊。這個變量是一個對象。
在模塊的內部,this指向的是當前模塊的導出對象。 this \\u003d\\u003d\\u003d module.exports 是 true。
最開始的 requireJS 是同步加載,這在瀏覽器中會阻止頁麵渲染,導致整個應用暫停。後續發明了 AMD (Asynchronous Module Definition) 來解決這個問題。
AMD 采用異步方式加載模塊,模塊的加載不影響它後麵語句的運行。如下:
require(\\u0027.\/csaj.js\\u0027) \/\/ 同步加載
require([\\u0027.\/csaj.js\\u0027],function(){}) \/\/ 異步加載
當然同樣的異步加載模塊方式還有 CMD , 兩者的區別在於 對依賴模塊的執行時機處理不同。
加載的時機或者方式是相同的,AMD 、CMD 皆為異步加載模塊
ES6標準發布後,module成為標準,標準使用是以export指令導出接口,以import引入模塊。
require\/module.exports屬於CommonJS規範。 import\/export屬於ES6規範。
二.require
2-1.運行機製
模塊的exports屬性(即module.exports)是對外的接口。加載某個模塊,其實是加載該模塊的module.exports屬性。
通過require加載模塊的流程:(1)找到需要加在的模塊文件。 (2)找到需要加在的模塊文件。 (3)把讀取到的內容放到一個自執行函數中執行。(4)返回module.exports需要導出的內容。
(function (exports, require, module, __filename, __dirname) {
\/\/模塊的代碼實際上在這裏
});
2-2.支持類型
NodeJS支持三種類型的文件,.js、.json、.node(C++擴展二進製模塊)。
模塊類型分為核心模塊、文件模塊、第三方模塊,其中核心模塊是編譯二進製文件,加載速度最快,比如 fs\/path\/http 等。
當嚐試加載一個不帶後綴的文件時,比如require(\\u0027.\/test\\u0027),會依次嚐試test\/test.js\/test.json\/test.node。
2-3.緩存
再看一下模塊的緩存,緩存可以通過require.cache查看,其返回一個對象,key是文件絕對路徑,value是Module對象。
最近遇到一個問題就是CommonJS的模塊緩存機製導致的,起初想通過改變.env.local文件,對多個項目一起打包。由於緩存機製,新寫入的環境變量,並不會被重新加載,也就導致了無法生效。
2-4.特點
CommonJS加載的是一個對象(module.exports屬性),隻有腳本運行時該對象才會確定,所以CommonJS是運行時加載。