第13章 NodeJS的require(1 / 2)

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是運行時加載。