js 模塊化

歷史上JavaScript一直沒有模塊體系,在其他高級(jí)語言中顾孽,Java有類文件祝钢,Python有import機(jī)制,Ruby有require若厚,PHP有include和require太颤。而JavaScript則是通過<script>標(biāo)簽引入代碼,顯得雜亂無章盹沈。人們不得不用命名空間等方式人為地約束代碼,以求達(dá)到安全和易用的目的。

為此乞封,社區(qū)指定了一些模塊加載方案做裙,最主要的有CommonJS,AMD和CMD三種肃晚。前者用于服務(wù)器锚贱,后兩者用于瀏覽器。同時(shí)关串,ES6也從語言規(guī)格的層面上拧廊,實(shí)現(xiàn)了模塊功能,完全可以代替CommonJS晋修,AMD和CMD吧碾,成為瀏覽器和服務(wù)器通用的模塊解決方案。

下面將就上面這四種方案進(jìn)行簡單介紹墓卦。

CommonJS

CommonJS是服務(wù)器端模塊的規(guī)范倦春,它的提出主要是為了彌補(bǔ)當(dāng)前JavaScript沒有標(biāo)準(zhǔn)的缺陷,以達(dá)到像Python落剪,Java具備大型應(yīng)用開發(fā)大型應(yīng)用的基礎(chǔ)能力睁本,而不是停留在小腳本程序的階段。NodeJS采取的就是CommonJS規(guī)范忠怖。

CommonJS對(duì)模塊的定義很簡單呢堰,主要分為模塊引用,模塊定義和模塊標(biāo)識(shí)3個(gè)方面凡泣。

模塊引用

模塊引用的實(shí)例如下

var math = require('math');

在CommonJS規(guī)范中枉疼,存在require()方法,這個(gè)方法接受模塊標(biāo)識(shí)问麸,以此引入一個(gè)模塊的API到當(dāng)前上下文中往衷。

模塊定義

在模塊中,上下文提供require()方法來引入外部模塊严卖。對(duì)應(yīng)引入的功能站超,上下文提供了exports對(duì)象用于導(dǎo)出當(dāng)前模塊的方法或者變量,并且它是唯一導(dǎo)出的出口掺冠。在模塊中嗡午,還存在一個(gè)module對(duì)象,它代表模塊自身稠肘,而exports是module的屬性福铅。在Node中,一個(gè)文件就是一個(gè)模塊项阴,將方法掛在在exports對(duì)象上作為屬性即可定義導(dǎo)出的方式:

// math.js
exports.add = function() {
    var sum = 0,
    i = 0,
    args = arguments,
    l = arguments.length;
        while(i < 1) {
        sum += args[i++];
    }       
    return sum;
}

在另一個(gè)文件中滑黔,我們通過require()方法來引入模塊后,就能調(diào)用定義的屬性和方法了:

//program.js
var math = require('math');
exports.increment = function(val) {
    return math.add(val, 1);
}

需要注意的是,module.exportsexports是相同的引用略荡,即

exports = module.exports

最終模塊返回的是module.exports庵佣。

所以下面的寫法是錯(cuò)誤的

exports = function(val) {
    return val + 1;
}

這樣做的話exports就不再指向module.exports。正確的寫法是

module.exports = function(val) {
  return val + 1;
}

模塊標(biāo)識(shí)

模塊標(biāo)識(shí)其實(shí)就是傳遞給require()方法的參數(shù)汛兜,它必須是符合駝峰名的字符串巴粪,或者以. , ..開頭的相對(duì)路徑,或者絕對(duì)路徑粥谬。它可以沒有文件名后綴.js肛根。

模塊的定義十分簡單,接口也十分簡潔漏策。它的意義在于將類聚的方法和變量等限定在私有的作用域中派哲,同時(shí)支持引入和引出功能以順暢的連接上下游依賴。每個(gè)模塊有獨(dú)立的空間哟玷,它們互不干擾狮辽,在引用時(shí)也顯得干凈利落。

AMD

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

AMD異步加載所需的模塊喉脖,然后在回調(diào)函數(shù)中執(zhí)行主邏輯。這正是我們在瀏覽器端開發(fā)所習(xí)慣了的方式抑月。

AMD規(guī)范的模塊定義如下:

define(id?, dependencies?, factory)

它的模塊id和依賴是可選的树叽,factory的內(nèi)容就是實(shí)際代碼的內(nèi)容。下面的代碼簡單的定義了兩個(gè)模塊谦絮。

// a.js
define(function(){
    var exports = {};
    exports.sayHello = function() {
      alert("Hello from module: " + module.id);
    };
    return exports;
});

// b.js
define(['a'], function(a) {
    a.sayHello();
});

AMD與CommonJS規(guī)范的Node不同的是AMD模塊需要用define來明確定義一個(gè)模塊题诵,而Node是隱式包裝的,它們的目的都是為了進(jìn)行作用域的隔離层皱,僅在需要的時(shí)候被引入性锭;另一個(gè)不同是AMD的內(nèi)容需要通過返回的方式實(shí)現(xiàn)導(dǎo)出。

CMD

CMD與AMD規(guī)范的主要區(qū)別在于定義模塊和依賴模塊引入的部分叫胖。AMD需要在聲明模塊的時(shí)候指定所有的依賴草冈,通過形參傳遞到依賴模塊內(nèi)容中:

 define(['dep1', 'dep2'], function(dep1, dep2){
    return function(){};
});

與AMD模塊相比,CMD模塊更接近于Node對(duì)CommonJS規(guī)范的定義:

define(factory);

在依賴部分瓮增,CMD支持動(dòng)態(tài)引入怎棱,示例如下:

define(function(require, exports, module){

   // 獲取模塊a的接口
   var a = require('./a');

   // 調(diào)用模塊a的方法
   a.doSomething();

});

CommonJS, AMD, CMD 區(qū)別

CommonJS加載模塊是同步的,所以只有加載完成后才能執(zhí)行后面的操作绷跑,像NodeJS主要用于服務(wù)器端的編程拳恋,加載的模塊文件一般都已存在本地硬盤,所以加載起來比較快砸捏,不用考慮異步加載的方式谬运,所以CommonJS規(guī)范比較適用隙赁。但如果是瀏覽器環(huán)境,要從服務(wù)器加載模塊吩谦,這時(shí)就必須采用異步模式鸳谜。所以就有了AMD,CMD解決方案式廷。

  • 對(duì)于依賴的模塊,AMD是提前執(zhí)行芭挽,CMD是推遲執(zhí)行滑废。
  • CMD推崇依賴就近,AMD推崇依賴前置袜爪。
// CMD
define(function(require, exports, module)){
    var a = require('./a');
    a.doSomething();
        
    var b = require('./b');
    b.doSomething();
}
    
// AMD
define(['./a', './b'], function(a, b) {
    a.doSomething();
    b.doSomething();
});
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蠕趁,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子辛馆,更是在濱河造成了極大的恐慌俺陋,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昙篙,死亡現(xiàn)場離奇詭異腊状,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)苔可,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門缴挖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人焚辅,你說我怎么就攤上這事映屋。” “怎么了同蜻?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵棚点,是天一觀的道長。 經(jīng)常有香客問我湾蔓,道長瘫析,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任卵蛉,我火速辦了婚禮颁股,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘傻丝。我一直安慰自己甘有,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布葡缰。 她就那樣靜靜地躺著亏掀,像睡著了一般忱反。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上滤愕,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天温算,我揣著相機(jī)與錄音,去河邊找鬼间影。 笑死注竿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的魂贬。 我是一名探鬼主播巩割,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼付燥!你這毒婦竟也來了宣谈?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤键科,失蹤者是張志新(化名)和其女友劉穎闻丑,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體勋颖,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嗦嗡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了牙言。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酸钦。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖咱枉,靈堂內(nèi)的尸體忽然破棺而出卑硫,到底是詐尸還是另有隱情,我是刑警寧澤蚕断,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布欢伏,位于F島的核電站,受9級(jí)特大地震影響亿乳,放射性物質(zhì)發(fā)生泄漏硝拧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一葛假、第九天 我趴在偏房一處隱蔽的房頂上張望障陶。 院中可真熱鬧,春花似錦聊训、人聲如沸抱究。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鼓寺。三九已至勋拟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間妈候,已是汗流浹背敢靡。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留苦银,地道東北人啸胧。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像幔虏,于是被迫代替她去往敵國和親吓揪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

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

  • 什么是模塊化? 簡單理解:將各個(gè)功能封裝為獨(dú)立的模塊习勤,當(dāng)需要某個(gè)功能時(shí)踪栋,只需要加載相應(yīng)的模塊即可 為什么出現(xiàn)模塊化...
    放風(fēng)箏的小小馬閱讀 835評(píng)論 0 6
  • 一、js模塊化1图毕、模塊化規(guī)范: script CommonJS AMD CMD ES6 modules 2夷都、scr...
    大餅?zāi)榤e閱讀 406評(píng)論 0 0
  • 什么是模塊化? 1予颤,把你的代碼寫成模塊的2囤官,把這單獨(dú)的模塊寫在單獨(dú)的文件里 模塊化有什么好處? 1蛤虐,讓代碼更清晰2...
    PYFang閱讀 374評(píng)論 0 0
  • 什么是模塊化開發(fā)党饮? 前端開發(fā)中,起初只要在script標(biāo)簽中嵌入幾十上百行代碼就能實(shí)現(xiàn)一些基本的交互效果驳庭,后來js...
    半世韶華憶闌珊閱讀 650評(píng)論 0 0
  • 萬物生靈的嘆息:沒有什么是真正的公平刑顺。資源的稀缺決定了爭奪的存在,稀缺資源決定了萬物的發(fā)展饲常,萬物生靈為了生存相互競...
    WorldFuture閱讀 388評(píng)論 0 0