淺析AMD CMD CommonJS規(guī)范--javascript模塊化加載學(xué)習(xí)心得總結(jié)
來(lái)源:易賢網(wǎng) 閱讀:822 次 日期:2016-07-19 16:00:59
溫馨提示:易賢網(wǎng)小編為您整理了“淺析AMD CMD CommonJS規(guī)范--javascript模塊化加載學(xué)習(xí)心得總結(jié)”,方便廣大網(wǎng)友查閱!

這是一篇關(guān)于javascript模塊化AMD,CMD,CommonJS的學(xué)習(xí)總結(jié),作為記錄也給同樣對(duì)三種方式有疑問(wèn)的童鞋們,有不對(duì)或者偏差之處,望各位大神指出,不勝感激。

本篇默認(rèn)讀者大概知道require,seajs的用法(AMD,CMD用法),所以沒(méi)有加入使用語(yǔ)法。

1、為何而生:

 這三個(gè)規(guī)范都是為javascript模塊化加載而生的,都是在用到或者預(yù)計(jì)要用到某些模塊時(shí)候加載該模塊,使得大量的系統(tǒng)巨大的龐雜的代碼得以很好的組織和管理。模塊化使得我們?cè)谑褂煤凸芾泶a的時(shí)候不那么混亂,而且也方便了多人的合作。

2、那些規(guī)范們:

(1)、CommonJS 是一個(gè)有志于構(gòu)建 JavaScript 生態(tài)圈的組織。整個(gè)社區(qū)致力于提高 JavaScript 程序的可移植性和可交換性,無(wú)論是在服務(wù)端還是瀏覽器端。

a group with a goal of building up the JavaScript ecosystem for web servers, desktop and command line apps and in the browser.

一個(gè)有目標(biāo)的構(gòu)建JavaScript生態(tài)系統(tǒng)Web服務(wù)器組,在瀏覽器和命令行應(yīng)用程序和桌面。(他自己wiki上這么說(shuō)的)

這個(gè)組織呢制定了一些規(guī)范 (可以去他們網(wǎng)站看看 http://www.commonjs.org/)包括CommonJS Modules/1.0 規(guī)范,我們平時(shí)所說(shuō)的commonjs規(guī)范,說(shuō)的就是這個(gè)了。

“The CommonJS API will fill that gap by defining APIs that handle many common application needs, ultimately providing a standard library as rich as those of Python, Ruby and Java. ”--(出自 http://www.commonjs.org/)

所以說(shuō)Commonjs是一個(gè)更偏向于服務(wù)器端的規(guī)范。Node.js采用了這個(gè)規(guī)范。 根據(jù)CommonJS規(guī)范,一個(gè)單獨(dú)的文件就是一個(gè)模塊。加載模塊使用require方法,該方法讀 取一個(gè)文件并執(zhí)行,最后返回文件內(nèi)部的exports對(duì)象。

他又說(shuō)了,可以用在下面這些場(chǎng)景  ,所以他更明顯的偏向服務(wù)器端。當(dāng)然你也可以把它用在瀏覽器里邊(他們自己說(shuō)可以)。

•Server-side JavaScript applications

•Command line tools

•Desktop GUI-based applications

•Hybrid applications (Titanium, Adobe AIR)

(2)、AMD規(guī)范

Commonjs解決了模塊化的問(wèn)題,并且可以用在瀏覽器中,但是Commonjs是同步加載模塊,當(dāng)要用到該模塊了,現(xiàn)加載現(xiàn)用,這種同步機(jī)制到了瀏覽器里邊就有問(wèn)題了,加載速度啊啥的(覽器同步加載模塊會(huì)導(dǎo)致性能、可用性、調(diào)試和跨域訪問(wèn)等問(wèn)題)。

鑒于瀏覽器的特殊情況,又出現(xiàn)了一個(gè)規(guī)范,這個(gè)規(guī)范呢可以實(shí)現(xiàn)異步加載依賴(lài)模塊,并且會(huì)提前加載那就是AMD規(guī)范。AMD可以作為CommonJS模塊一個(gè)中轉(zhuǎn)的版本只要CommonJS沒(méi)有被用來(lái)同步的require調(diào)用。使用同步require調(diào)用的CommonJS代碼可以被轉(zhuǎn)換為使用回調(diào)風(fēng)格的AMD模塊加載器(https://github.com/amdjs/amdjs-api/wiki/AMD-(%E4%B8%AD%E6%96%87%E7%89%88)  (它說(shuō)的)。

下面是一個(gè)使用了簡(jiǎn)單CommonJS轉(zhuǎn)換的模塊定義(它是amd規(guī)范的一種用法):

代碼如下:

   define(function (require, exports, module) {

     var a = require('a'),

         b = require('b');

     exports.action = function () {};

   });

所以說(shuō)AMD和Commonjs是兼容的,只要稍稍調(diào)換一下調(diào)用方法就實(shí)現(xiàn)了同步加載(我很懷疑amd也是在commonjs基礎(chǔ)上加了個(gè)殼,然后并沒(méi)有找到其他的神馬說(shuō)明和支持的文字,找到了一定加到這)。

看一下AMD規(guī)范你會(huì)發(fā)現(xiàn),AMD基本都是提前說(shuō)明依賴(lài)模塊,然后預(yù)加載這些模塊,實(shí)際上這就要求你提前想好這些依賴(lài),提前寫(xiě)好,不然寫(xiě)代碼過(guò)程中要回到開(kāi)頭繼續(xù)添加依賴(lài)。

(3)、CMD

不知道是不是針對(duì)這個(gè)問(wèn)題,淘寶的玉伯大牛搞了個(gè)seajs出來(lái),并聲稱(chēng)這個(gè)規(guī)范是遵循CMD規(guī)范的,然后給出了這個(gè)規(guī)范的一個(gè)連接(打開(kāi)會(huì)發(fā)現(xiàn)draft字樣)。關(guān)于這個(gè)規(guī)范呢玉伯在知乎是這么說(shuō)的

”AMD 是 RequireJS 在推廣過(guò)程中對(duì)模塊定義的規(guī)范化產(chǎn)出。

CMD 是 SeaJS 在推廣過(guò)程中對(duì)模塊定義的規(guī)范化產(chǎn)出。

類(lèi)似的還有 CommonJS Modules/2.0 規(guī)范,是 BravoJS 在推廣過(guò)程中對(duì)模塊定義的規(guī)范化產(chǎn)出。

還有不少⋯⋯

所以這個(gè)規(guī)范實(shí)際上是為了Seajs的推廣然后搞出來(lái)的。那么看看SeaJS是怎么回事兒吧,基本就是知道這個(gè)規(guī)范了。

同樣Seajs也是預(yù)加載依賴(lài)js跟AMD的規(guī)范在預(yù)加載這一點(diǎn)上是相同的,明顯不同的地方是調(diào)用,和聲明依賴(lài)的地方。AMD和CMD都是用difine和require,但是CMD標(biāo)準(zhǔn)傾向于在使用過(guò)程中提出依賴(lài),就是不管代碼寫(xiě)到哪突然發(fā)現(xiàn)需要依賴(lài)另一個(gè)模塊,那就在當(dāng)前代碼用require引入就可以了,規(guī)范會(huì)幫你搞定預(yù)加載,你隨便寫(xiě)就可以了。但是AMD標(biāo)準(zhǔn)讓你必須提前在頭部依賴(lài)參數(shù)部分寫(xiě)好(沒(méi)有寫(xiě)好? 倒回去寫(xiě)好咯)。這就是最明顯的區(qū)別。

3、共生共處

由于CommonJS是服務(wù)器端的規(guī)范,更另外兩個(gè)標(biāo)準(zhǔn)實(shí)際不沖突。

AMD在國(guó)外用的更多,當(dāng)然國(guó)內(nèi)也是不少的,jQuery1,7版本開(kāi)始使用,Dojo在1.6版本開(kāi)始用,這已經(jīng)能夠證明它足夠牛x了。

CMD當(dāng)然也有很多人在用,但是基本都集中在國(guó)內(nèi),Seajs官網(wǎng)就展示了一大堆牛逼的公司在用(包括愛(ài)奇藝,騰訊微博,支付寶,淘寶等一大堆,去這看看http://seajs.org/docs/),估計(jì)小的不出名的也不計(jì)其數(shù)了,畢竟很多公司招聘都要求會(huì)seajs嘛。

所以三個(gè)規(guī)范目前都挺好(其實(shí)也主要是因?yàn)閖s么有自己的模塊加載機(jī)制,es6出來(lái)之后不知道會(huì)怎樣)。

當(dāng)我們寫(xiě)一個(gè)文件需要兼容不同的加載規(guī)范的時(shí)候怎么辦呢,看看下面的代碼。

(function (root, factory) { 

  if (typeof define === 'function' && define.amd) { 

    // AMD 

    define(['jquery', 'underscore'], factory); 

  } else if (typeof exports === 'object') { 

    // Node, CommonJS之類(lèi)的 

    module.exports = factory(require('jquery'), require('underscore')); 

  } else { 

    // 瀏覽器全局變量(root 即 window) 

    root.returnExports = factory(root.jQuery, root._); 

  } 

}(this, function ($, _) { 

  // 方法 

  function a(){}; // 私有方法,因?yàn)樗鼪](méi)被返回 (見(jiàn)下面) 

  function b(){}; // 公共方法,因?yàn)楸环祷亓?nbsp;

  function c(){}; // 公共方法,因?yàn)楸环祷亓?nbsp;

  // 暴露公共方法 

  return { 

    b: b, 

    c: c 

  } 

}));

這個(gè)代碼可以兼容各種加載規(guī)范了。

4、AMD和CMD的區(qū)別

下面這幾點(diǎn)是玉伯在知乎上說(shuō)的。

1. 對(duì)于依賴(lài)的模塊,AMD 是提前執(zhí)行,CMD 是延遲執(zhí)行。不過(guò) RequireJS 從 2.0 開(kāi)始,也改成可以延遲執(zhí)行(根據(jù)寫(xiě)法不同,處理方式不同)。CMD 推崇 as lazy as possible.

2. CMD 推崇依賴(lài)就近,AMD 推崇依賴(lài)前置。

3. AMD 的 API 默認(rèn)是一個(gè)當(dāng)多個(gè)用,CMD 的 API 嚴(yán)格區(qū)分,推崇職責(zé)單一。比如 AMD 里,require 分全局 require 和局部 require,都叫 require。CMD 里,沒(méi)有全局 require,而是根據(jù)模塊系統(tǒng)的完備性,提供 seajs.use 來(lái)實(shí)現(xiàn)模塊系統(tǒng)的加載啟動(dòng)。CMD 里,每個(gè) API 都簡(jiǎn)單純粹。

4. 還有一些細(xì)節(jié)差異,具體看這個(gè)規(guī)范的定義就好,就不多說(shuō)了。

( 好吧~第四點(diǎn)是不多說(shuō)了。。。。。。。。。)

5、AMD和CMD的一些相同

都有difine和require,而且調(diào)用方式實(shí)際都可以添加依賴(lài)參數(shù),也就是說(shuō)都可以用提供依賴(lài)參數(shù)的方式來(lái)實(shí)現(xiàn)預(yù)加載依賴(lài)模塊(但是不推薦因?yàn)? 注意:帶 id 和 deps 參數(shù)的 define 用法不屬于 CMD 規(guī)范,而屬于 Modules/Transport 規(guī)范。---來(lái)自:https://github.com/seajs/seajs/issues/242)。

AMD也可以在factory中使用require來(lái)現(xiàn)加載用到的模塊,但是這個(gè)模塊就不會(huì)預(yù)先加載,屬于用到才加載的同步加載了。

var a = require('a'); // 加載模塊a

有不妥之處,歡迎斧正。

以上這篇淺析AMD CMD CommonJS規(guī)范--javascript模塊化加載學(xué)習(xí)心得總結(jié)就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考

更多信息請(qǐng)查看網(wǎng)絡(luò)編程
由于各方面情況的不斷調(diào)整與變化,易賢網(wǎng)提供的所有考試信息和咨詢(xún)回復(fù)僅供參考,敬請(qǐng)考生以權(quán)威部門(mén)公布的正式信息和咨詢(xún)?yōu)闇?zhǔn)!

2025國(guó)考·省考課程試聽(tīng)報(bào)名

  • 報(bào)班類(lèi)型
  • 姓名
  • 手機(jī)號(hào)
  • 驗(yàn)證碼
關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡(jiǎn)要咨詢(xún) | 簡(jiǎn)要咨詢(xún)須知 | 新媒體/短視頻平臺(tái) | 手機(jī)站點(diǎn) | 投訴建議
工業(yè)和信息化部備案號(hào):滇ICP備2023014141號(hào)-1 云南省教育廳備案號(hào):云教ICP備0901021 滇公網(wǎng)安備53010202001879號(hào) 人力資源服務(wù)許可證:(云)人服證字(2023)第0102001523號(hào)
云南網(wǎng)警備案專(zhuān)用圖標(biāo)
聯(lián)系電話(huà):0871-65099533/13759567129 獲取招聘考試信息及咨詢(xún)關(guān)注公眾號(hào):hfpxwx
咨詢(xún)QQ:1093837350(9:00—18:00)版權(quán)所有:易賢網(wǎng)
云南網(wǎng)警報(bào)警專(zhuān)用圖標(biāo)