AMD、CMD、requirejs

題目1: 為什么要使用模塊化?

模塊化可以使代碼低耦合,功能模塊直接不相互影響。

1.可維護性:根據(jù)定義,每個模塊都是獨立的。良好設計的模塊會盡量與外部的代碼撇清關系,以便于獨立對其進行改進和維護。維護一個獨立的模塊比起一團凌亂的代碼來說要輕松很多。
2.命名空間:在JavaScript中,最高級別的函數(shù)外定義的變量都是全局變量(這意味著所有人都可以訪問到它們)。也正因如此,當一些無關的代碼碰巧使用到同名變量的時候,我們就會遇到“命名空間污染”的問題。
3.提高代碼的可復用性。
4.進行依賴管理。

題目2: CMD、AMD、CommonJS 規(guī)范分別指什么?有哪些應用

Asynchronous Module Definition (AMD)/(異步模塊定義)

它推崇依賴前置,采用異步方式加載模塊,模塊的加載不影響它后面語句的運行。所有依賴這個模塊的語句,都定義在一個回調(diào)函數(shù)中,等到加載完成之后,這個回調(diào)函數(shù)才會運行。
特點/缺點:

  • 依賴前置,需要在定義的時候,寫好需要的依賴。
  • 多個JS有依賴關系。被依賴的JS需要早于依賴它的文件提前加入。
  • JS加載的時候,頁面會停止渲染。加載的文件越多。頁面失去響應的時間越長。

應用:Reauire.js

//定義模塊:
define(id ?, dependencies?, function)
-----------------------------------------------
//id:可選參數(shù),用來定義模塊標識。如果沒有寫,就用文件名。
//denpendencies:當前的模塊依賴的模塊,數(shù)組形式。
//function:執(zhí)行的函數(shù)
//加載模塊
require([dependencies], function)
//---------------------------------------------
//dependencies:當前模塊需要的依賴的模塊。
//function:回調(diào)函數(shù),在模塊加載完了后,會被執(zhí)行。
//require是異步執(zhí)行。在依賴模塊沒有被加載完。是不會執(zhí)行回調(diào)函數(shù)的。同時瀏覽器不會失去響應。

Common Module Definition ——(CMD)

通用模塊定義,是一種模塊定義方式和模塊加載方式的規(guī)范

  • 依賴就近,需要的時候再引入這個依賴項,用的時候再require。
  • 推崇一個文件一個模塊,所以經(jīng)常將文件名作為模塊id
  • 因推崇依賴就近,所以一般不在define的參數(shù)中寫依賴,在factory中寫。

應用:sea.js

define(function(require,exports,module){})
//require:獲取其他的模塊提供的接口。
//exports:對外提供模塊的接口。
//module是個對象,上面存儲了與當前模塊相關的屬性和方法
//定義模塊
define(function(require, exports, module){
  var $ = require('jquery.js')
  $('div').removeClass('active')
})

 //加載模塊
seajs.use(['myModule.js'], function(my){
  
})

AMD與CMD的差別是:AMD是首先加載所有模塊,再執(zhí)行,而CMD是按需加載。AMD依賴前置,js可以方便知道依賴模塊是誰,立即加載;而CMD就近依賴,需要使用把模塊變?yōu)樽址馕鲆槐椴胖酪蕾嚵四切┠K,這也是很多人詬病CMD的一點,犧牲性能來帶來開發(fā)的便利性,實際上解析模塊用的時間短到可以忽略。如今requireJS和seaJS都已經(jīng)是過去時,webpack和Browserify成為主流

CommonJS

  • 一個單獨的文件就是一個模塊,每個模塊都是一個單獨的作用域
    在模塊內(nèi)部定義的變量,無法被其他模塊讀取,除非定義為global對象的屬性
  • 模塊輸出:模塊只有一個出口,module.exports對象,我們需要把模塊希望輸出的內(nèi)容放入該對象
  • 加載模塊:加載模塊使用require方法,該方法讀取一個文件并執(zhí)行,返回 文件內(nèi)部的module.exports對象,如果請求的模塊不能返回,那么”require”必須拋出一個錯誤。
//定義模塊 myModule.js
var name =  'mamba'

function printName(){
  console.log(name)
}

function printFullName(firstName){
    console.log(firstName + name);
}

//輸出模塊
module.exports = {
    printName: printName,
    printFullName: printFullName
}

//加載模塊
var nameModule = require('./myModule.js') //不同的實現(xiàn)對require時的路徑有不同要求,一般情況可以省略js拓展名,可以使用相對路徑,也可以使用絕對路徑,甚至可以省略路徑直接使用模塊名(前提是該模塊是系統(tǒng)內(nèi)置模塊)

//使用模塊
nameModule.printName();

應用:因為require是同步的,所以主要在服務器端使用
瀏覽器端加載JavaScript是異步的,所以傳統(tǒng)的CommonJS在瀏覽器環(huán)境中無法正常加載。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容

  • 為什么要使用模塊化? 最主要的目的:解決命名沖突依賴管理 其他價值提高代碼可讀性代碼解耦,提高復用性 CMD、AM...
    Eazer閱讀 693評論 3 1
  • 題目1: 為什么要使用模塊化? 模塊的由來:嵌入網(wǎng)頁的JS代碼越來越龐大,越來越像桌面程序,需要一個團隊去分工協(xié)作...
    蕭雪圣閱讀 286評論 0 0
  • 題目1: 為什么要使用模塊化? 最主要的目的:1.解決命名沖突2.依賴管理其他價值:1.提高代碼可讀性2.代碼解耦...
    saintkl閱讀 320評論 0 0
  • 題目1: 為什么要使用模塊化? 解決命名沖突 依賴管理 提高代碼可讀性 代碼解耦,提高復用性 題目2: CMD、A...
    撫年華輕過閱讀 352評論 0 0
  • (44)致良知是一種偉大的力量! 2017年7月14星期五 涌泉學苑學習班第期 第44天 【涌泉學苑期北大群23孫...
    聞君兒閱讀 296評論 0 1