CommonJS AMD CMD UMD

CommonJS

CommonJS是服務(wù)器端模塊的規(guī)范噪舀,Node.js采用了這個(gè)規(guī)范。

根據(jù)CommonJS規(guī)范蒂誉,一個(gè)單獨(dú)的文件就是一個(gè)模塊怖侦。加載模塊使用require方法篡悟,該方法讀取一個(gè)文件并執(zhí)行,最后返回文件內(nèi)部的exports對(duì)象匾寝。

例如:

// foobar.js

//私有變量

var test = 123;

//公有方法

function foobar () {

this.foo = function () {

// do someing ...

}

this.bar = function () {

//do someing ...

}

}

//exports對(duì)象上的方法和變量是公有的

var foobar = new foobar();

exports.foobar = foobar;

//require方法默認(rèn)讀取js文件搬葬,所以可以省略js后綴

var test = require('./boobar').foobar;

test.bar();

CommonJS 加載模塊是同步的,所以只有加載完成才能執(zhí)行后面的操作艳悔。像Node.js主要用于服務(wù)器的編程急凰,加載的模塊文件一般都已經(jīng)存在本地硬盤,所以加載起來比較快猜年,不用考慮異步加載的方式抡锈,所以CommonJS規(guī)范比較適用疾忍。但如果是瀏覽器環(huán)境,要從服務(wù)器加載模塊企孩,這是就必須采用異步模式。所以就有了 AMD CMD 解決方案袁稽。

AMD是"Asynchronous Module Definition"的縮寫勿璃,意思就是"異步模塊定義".

AMD設(shè)計(jì)出一個(gè)簡(jiǎn)潔的寫模塊API:

define(id?, dependencies?, factory);

第一個(gè)參數(shù) id 為字符串類型,表示了模塊標(biāo)識(shí)推汽,為可選參數(shù)补疑。若不存在則模塊標(biāo)識(shí)應(yīng)該默認(rèn)定義為在加載器中被請(qǐng)求腳本的標(biāo)識(shí)。如果存在歹撒,那么模塊標(biāo)識(shí)必須為頂層的或者一個(gè)絕對(duì)的標(biāo)識(shí)莲组。

第二個(gè)參數(shù),dependencies 暖夭,是一個(gè)當(dāng)前模塊依賴的锹杈,已被模塊定義的模塊標(biāo)識(shí)的數(shù)組字面量。

第三個(gè)參數(shù)迈着,factory竭望,是一個(gè)需要進(jìn)行實(shí)例化的函數(shù)或者一個(gè)對(duì)象。

RequireJS

RequireJS 是一個(gè)前端的模塊化管理的工具庫(kù)裕菠,遵循AMD規(guī)范咬清,它的作者就是AMD規(guī)范的創(chuàng)始人 James Burke。所以說RequireJS是對(duì)AMD規(guī)范的闡述一點(diǎn)也不為過奴潘。

RequireJS 的基本思想為:通過一個(gè)函數(shù)來將所有所需要的或者說所依賴的模塊實(shí)現(xiàn)裝載進(jìn)來旧烧,然后返回一個(gè)新的函數(shù)(模塊),我們所有的關(guān)于新模塊的業(yè)務(wù)代碼都在這個(gè)函數(shù)內(nèi)部操作画髓,其內(nèi)部也可無限制的使用已經(jīng)加載進(jìn)來的以來的模塊掘剪。

<script data-main='scripts/main' src='scripts/require.js'></script>

那么scripts下的main.js則是指定的主代碼腳本文件,所有的依賴模塊代碼文件都將從該文件開始異步加載進(jìn)入執(zhí)行奈虾。

define用于定義模塊杖小,RequireJS要求每個(gè)模塊均放在獨(dú)立的文件之中。按照是否有依賴其他模塊的情況分為獨(dú)立模塊和非獨(dú)立模塊愚墓。

獨(dú)立模塊予权,不依賴其他模塊。直接定義:

define({

method1: function(){},

method2: function(){}

});

也等價(jià)于

define(function() {

return {

method1: function(){},

method2: function(){}

}

});

非獨(dú)立模塊浪册,對(duì)其他模塊有依賴扫腺。

define([ 'module1', 'module2' ], function(m1, m2) {

...

});

或者:

define(function(require) {

var m1 = require('module1'),

m2 = require('module2');

...

});

簡(jiǎn)單看了一下RequireJS的實(shí)現(xiàn)方式,其 require 實(shí)現(xiàn)只不過是提取 require 之后的模塊名村象,將其放入依賴關(guān)系之中笆环。

require方法調(diào)用模塊

在require進(jìn)行調(diào)用模塊時(shí)攒至,其參數(shù)與define類似。

require(['foo', 'bar'], function(foo, bar) {

foo.func();

bar.func();

} );

在加載 foo 與 bar 兩個(gè)模塊之后執(zhí)行回調(diào)函數(shù)實(shí)現(xiàn)具體過程躁劣。

當(dāng)然還可以如之前的例子中的迫吐,在define定義模塊內(nèi)部進(jìn)行require調(diào)用模塊

define(function(require) {

var m1 = require( 'module1' ),

m2 = require( 'module2' );

...

});

define 和 require 這兩個(gè)定義模塊,調(diào)用模塊的方法合稱為AMD模式账忘,定義模塊清晰志膀,不會(huì)污染全局變量,清楚的顯示依賴關(guān)系鳖擒。AMD模式可以用于瀏覽器環(huán)境并且允許非同步加載模塊溉浙,也可以按需動(dòng)態(tài)加載模塊。

官網(wǎng) (http://www.requirejs.org/)

API http://www.requirejs.org/docs/api.html

RequireJS is a JavaScript file and module loader. It is optimized for in-browser use, but it can be used in other JavaScript environments, like Rhino and Node. Using a modular script loader like RequireJS will improve the speed and quality of your code.

為什么說like Rhino and Node. 而不是like Rhino and V8

http://www.requirejs.org/docs/node.html

Mozilla Rhino 是一個(gè)完全使用Java語言編寫的開源JavaScript引擎實(shí)現(xiàn),主要用于在java環(huán)境中執(zhí)行xxx.js 或者 js程序蒋荚。Rhino通常用于在Java程序中戳稽,為最終用戶提供腳本化能力。Rhino(犀牛)這個(gè)名字來源于O'Reilly出版的著名的“犀牛書”JavaScript: The Definitive Guide(中文譯名:JavaScript權(quán)威指南)期升。

V8使用C++開發(fā)惊奇,并在谷歌瀏覽器中使用。在運(yùn)行JavaScript之前播赁,相比其它的JavaScript的引擎轉(zhuǎn)換成字節(jié)碼或解釋執(zhí)行赊时,V8將其編譯成原生機(jī)器碼(IA-32, x86-64, ARM, or MIPS CPUs),并且使用了如內(nèi)聯(lián)緩存(inline caching)等方法來提高性能行拢。有了這些功能祖秒,JavaScript程序在V8引擎下的運(yùn)行速度媲美二進(jìn)制程序。

Node.js 是一個(gè)基于 Chrome V8 引擎的 JavaScript 運(yùn)行環(huán)境舟奠。

Node.js 使用了一個(gè)事件驅(qū)動(dòng)竭缝、非阻塞式 I/O 的模型,使其輕量又高效沼瘫。

Node.js 的包管理器 npm抬纸,是全球最大的開源庫(kù)生態(tài)系統(tǒng)。

CMD

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

SeaJS

官網(wǎng) http://seajs.org/docs/

API快速參考 https://github.com/seajs/seajs/issues/266

對(duì)于依賴的模塊AMD是提前執(zhí)行耿戚,CMD是延遲執(zhí)行湿故。不過RequireJS從2.0開始,也改成可以延遲執(zhí)行(根據(jù)寫法不同膜蛔,處理方式不通過)坛猪。

CMD推崇依賴就近,AMD推崇依賴前置皂股。

//AMD

define(['./a','./b'], function (a, b) {

//依賴一開始就寫好

a.test();

b.test();

});

//CMD

define(function (requie, exports, module) {

//依賴可以就近書寫

var a = require('./a');

a.test();

...

//軟依賴

if (status) {

var b = requie('./b');

b.test();

}

});

UMD是AMD和CommonJS的糅合

AMD模塊以瀏覽器第一的原則發(fā)展墅茉,異步加載模塊。

CommonJS模塊以服務(wù)器第一原則發(fā)展,選擇同步加載就斤,它的模塊無需包裝(unwrapped modules)悍募。

這迫使人們又想出另一個(gè)更通用的模式UMD (Universal Module Definition)。希望解決跨平臺(tái)的解決方案洋机。

UMD先判斷是否支持Node.js的模塊(exports)是否存在坠宴,存在則使用Node.js模塊模式。再判斷是否支持AMD(define是否存在)绷旗,存在則使用AMD方式加載模塊喜鼓。

(function (window, factory) {

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

module.exports = factory();

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

define(factory);

} else {

window.eventUtil = factory();

}

})(this, function () {

//module ...

});

SeaJs和RequireJs區(qū)別

1.定位有差異。RequireJS 想成為瀏覽器端的模塊加載器刁标,同時(shí)也想成為 Rhino / Node 等環(huán)境的模塊加載器颠通。Sea.js 則專注于 Web 瀏覽器端址晕,同時(shí)通過 Node 擴(kuò)展的方式可以很方便跑在 Node 環(huán)境中膀懈。

2.遵循的規(guī)范不同。RequireJS 遵循 AMD(異步模塊定義)規(guī)范谨垃,Sea.js 遵循 CMD (通用模塊定義)規(guī)范启搂。規(guī)范的不同,導(dǎo)致了兩者 API 不同刘陶。Sea.js 更貼近 CommonJS Modules/1.1 和 Node Modules 規(guī)范胳赌。

3.推廣理念有差異。RequireJS 在嘗試讓第三方類庫(kù)修改自身來支持 RequireJS匙隔,目前只有少數(shù)社區(qū)采納疑苫。Sea.js 不強(qiáng)推,采用自主封裝的方式來“海納百川”纷责,目前已有較成熟的封裝策略捍掺。

4.對(duì)開發(fā)調(diào)試的支持有差異。Sea.js 非常關(guān)注代碼的開發(fā)調(diào)試再膳,有 nocache挺勿、debug 等用于調(diào)試的插件。RequireJS 無這方面的明顯支持喂柒。

5.插件機(jī)制不同不瓶。RequireJS 采取的是在源碼中預(yù)留接口的形式,插件類型比較單一灾杰。Sea.js 采取的是通用事件機(jī)制蚊丐,插件類型更豐富。

https://www.douban.com/note/283566440/

OzJs

http://ozjs.org/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末艳吠,一起剝皮案震驚了整個(gè)濱河市吠撮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖泥兰,帶你破解...
    沈念sama閱讀 221,331評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件弄屡,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡鞋诗,警方通過查閱死者的電腦和手機(jī)膀捷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,372評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來削彬,“玉大人全庸,你說我怎么就攤上這事∪谕矗” “怎么了壶笼?”我有些...
    開封第一講書人閱讀 167,755評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)雁刷。 經(jīng)常有香客問我覆劈,道長(zhǎng),這世上最難降的妖魔是什么沛励? 我笑而不...
    開封第一講書人閱讀 59,528評(píng)論 1 296
  • 正文 為了忘掉前任责语,我火速辦了婚禮,結(jié)果婚禮上目派,老公的妹妹穿的比我還像新娘坤候。我一直安慰自己,他們只是感情好企蹭,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,526評(píng)論 6 397
  • 文/花漫 我一把揭開白布白筹。 她就那樣靜靜地躺著,像睡著了一般谅摄。 火紅的嫁衣襯著肌膚如雪徒河。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,166評(píng)論 1 308
  • 那天螟凭,我揣著相機(jī)與錄音虚青,去河邊找鬼。 笑死螺男,一個(gè)胖子當(dāng)著我的面吹牛棒厘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播下隧,決...
    沈念sama閱讀 40,768評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼奢人,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了淆院?” 一聲冷哼從身側(cè)響起何乎,我...
    開封第一講書人閱讀 39,664評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后支救,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體抢野,經(jīng)...
    沈念sama閱讀 46,205評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,290評(píng)論 3 340
  • 正文 我和宋清朗相戀三年各墨,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了指孤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,435評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡贬堵,死狀恐怖恃轩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情黎做,我是刑警寧澤叉跛,帶...
    沈念sama閱讀 36,126評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站蒸殿,受9級(jí)特大地震影響筷厘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜伟桅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,804評(píng)論 3 333
  • 文/蒙蒙 一敞掘、第九天 我趴在偏房一處隱蔽的房頂上張望叽掘。 院中可真熱鬧楣铁,春花似錦、人聲如沸更扁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,276評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽浓镜。三九已至溃列,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間膛薛,已是汗流浹背听隐。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留哄啄,地道東北人雅任。 一個(gè)月前我還...
    沈念sama閱讀 48,818評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像咨跌,于是被迫代替她去往敵國(guó)和親沪么。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,442評(píng)論 2 359

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