JS模塊化規(guī)范:AMD谷誓,CMD,CommonJS和ES6

之前公司開發(fā)的某個(gè)大數(shù)據(jù)產(chǎn)品吨凑,所有的功能都集中在了一個(gè)頁(yè)面里面片林,久而久之就造成了頁(yè)面加載卡頓大大影響了體驗(yàn)效果;后來(lái)引用了RequireJS來(lái)進(jìn)行模塊化的開發(fā)來(lái)解決這個(gè)問題怀骤;不管從前后端未分離的RequireJS還是使用Node開發(fā)的CommonJS,模塊化開發(fā)無(wú)處不在,模塊化的開發(fā)方式可以提高代碼復(fù)用率焕妙,方便進(jìn)行代碼的管理蒋伦。通常一個(gè)文件就是一個(gè)模塊,有自己的作用域籽慢,只向外暴露它的接口硼瓣。目前流行的js模塊化規(guī)范有CommonJS、AMD牲证、CMD以及ES6的模塊系統(tǒng)研叫。那么在眾多模塊化開發(fā)方案當(dāng)中我們應(yīng)該使用哪種方案锤窑?

原始方法

<script>標(biāo)簽

這是最原始的 JavaScript 文件加載方式,如果把每一個(gè)文件看做是一個(gè)模塊嚷炉,那么他們的接口通常是暴露在全局作用域下渊啰,也就是定義在window對(duì)象中,不同模塊的接口調(diào)用都是一個(gè)作用域中申屹,一些復(fù)雜的框架绘证,會(huì)使用命名空間的概念來(lái)組織這些模塊的接口。

這種原始的加載方式暴露了一些顯而易見的弊端:

全局作用域下容易造成變量沖突

文件只能按照<script>的書寫順序進(jìn)行加載

開發(fā)人員必須主觀解決模塊和代碼庫(kù)的依賴關(guān)系

在大型項(xiàng)目中各種資源難以管理哗讥,長(zhǎng)期積累的問題導(dǎo)致代碼庫(kù)混亂不堪

一嚷那、CommonJS

我們?cè)谑褂肗ode開發(fā)程序的時(shí)候,這個(gè)程序由很多個(gè)模塊組成杆煞,每一個(gè)模塊都是一個(gè)文件(一個(gè)單獨(dú)的作用域)魏宽。Node模塊采用的就是CommonJS規(guī)范,該規(guī)范的核心思想是允許模塊通過?require?方法來(lái)同步加載所要依賴的其他模塊决乎,然后通過? module.exports?來(lái)導(dǎo)出需要暴露的接口队询。

CommonJS是服務(wù)端的JS規(guī)范,上面提到了每個(gè)文件都是一個(gè)作用域瑞驱,在該模塊內(nèi)部定義的變量其他模塊沒有辦法讀取的到娘摔,除非定義為global對(duì)象的屬性,

輸出模塊: 每個(gè)模塊只有一個(gè)出口唤反, module.export對(duì)象凳寺,我們把想要輸出的模塊放入里面;

加載模塊: 加載一個(gè)模塊的時(shí)候我們采用require方法彤侍,這個(gè)方法會(huì)讀取一個(gè)文件并返回文件內(nèi)部的module.export對(duì)象肠缨;

CommonJS模塊的特點(diǎn)如下。

1盏阶、所有代碼都運(yùn)行在模塊作用域晒奕,不會(huì)污染全局作用域。

2名斟、模塊可以多次加載脑慧,但是只會(huì)在第一次加載時(shí)運(yùn)行一次,然后運(yùn)行結(jié)果就被緩存了砰盐,以后再加載闷袒,就直接讀取緩存結(jié)果。要想讓模塊再次運(yùn)行岩梳,必須清除緩存囊骤。

3晃择、NMP中已經(jīng)有將近20萬(wàn)個(gè)可以使用模塊包

缺點(diǎn):

1、同步的模塊加載方式不適合在瀏覽器環(huán)境中也物,同步意味著阻塞加載宫屠,

2、瀏覽器資源是異步加載的不能非阻塞的并行加載多個(gè)模塊

?CommonJs所加載的模塊一般都已經(jīng)存在本地的硬盤里面滑蚯,當(dāng)我們執(zhí)行某個(gè)文件的時(shí)候會(huì)一同加載文件里面require所引入的文件浪蹂,加載起來(lái)非常快膘魄,不要考慮異步加載的方式乌逐。 但是這個(gè)只是在于服務(wù)器端,如果是瀏覽器端创葡,要從服務(wù)器加載模塊就必須采用異步的方式浙踢,于是乎就有了AMD CMD的解決方案;

二灿渴、AMD

Asynchronous Module Definition(?異步模塊定義)洛波。它是一個(gè)在瀏覽器端模塊化開發(fā)的規(guī)范。它不是javascript原生支持骚露,所以使用AMD規(guī)范進(jìn)行頁(yè)面開發(fā)需要用到對(duì)應(yīng)的庫(kù)蹬挤,也就是RequireJS,AMD其實(shí)是RequireJS在推廣的過程中對(duì)模塊定義的范圍化的產(chǎn)出棘幸。

它的實(shí)現(xiàn)方案是:先定義所有依賴焰扳,然后在加載完成后的回調(diào)函數(shù)中執(zhí)行。

AMD是預(yù)加載, 只有一個(gè)接口:define(id?,dependencies?,factory);?它要在聲明模塊的時(shí)候制定所有的依賴(dep)误续,并且還要當(dāng)做形參傳到factory中吨悍,注意的是這些依賴文件并沒有書寫順序的區(qū)別;

但是開始就把所有依賴寫出來(lái)是不符合書寫的邏輯順序的蹋嵌,能不能像commonJS那樣用的時(shí)候再require育瓜,而且還支持異步加載后再執(zhí)行呢?

優(yōu)點(diǎn):

適合在瀏覽器環(huán)境中異步加載模塊

可以并行加載多個(gè)模塊

缺點(diǎn):

提高了開發(fā)成本栽烂,代碼的閱讀和書寫比較困難躏仇,模塊定義方式的語(yǔ)義不順暢

不符合通用的模塊化思維方式,是一種妥協(xié)的實(shí)現(xiàn)

三腺办、CMD

CMD是另一種js模塊化方案焰手,它與AMD很類似,不同點(diǎn)在于:AMD 推崇依賴前置怀喉、提前執(zhí)行册倒,CMD推崇依賴就近、延遲執(zhí)行磺送。

Common Module Definition(CMD),??是seajs推崇的規(guī)范驻子,CMD則是依賴就近,用的時(shí)候再require估灿。CMD 推崇 as lazy as possible(盡可能的懶加載崇呵,也稱為延遲加載,即在需要的時(shí)候才加載)馅袁。

AMD 和 CMD 的書寫區(qū)別:

AMD依賴前置域慷,在定義模塊時(shí)就聲明其所要依賴的模塊

CMD是按需加載依賴,在用到那個(gè)模塊再去require

AMD在使用前就準(zhǔn)備好汗销,CMD是用到了再去準(zhǔn)備模塊

優(yōu)點(diǎn):

1犹褒、依賴就近,延遲執(zhí)行

2弛针、可以很容易在 Node.js 中運(yùn)行

缺點(diǎn):依賴 SPM 打包叠骑,模塊的加載邏輯偏重




現(xiàn)在我們?cè)賮?lái)說說ES6標(biāo)準(zhǔn)的模塊化:

ES6靜態(tài)加載的設(shè)計(jì)思想,使得在編譯時(shí)就可以確定模塊的依賴關(guān)系削茁,以及輸入宙枷、輸出的變量。ES6則在語(yǔ)言層面上實(shí)現(xiàn)了模塊化茧跋,取代CommonJS慰丛、AMD、CMD成為服務(wù)端和瀏覽器端通用的模塊解決方案瘾杭。(CommonJS诅病、AMD、CMD運(yùn)行時(shí)確定依賴關(guān)系)

ES6模塊和CommonJS的區(qū)別

CommonJS模塊輸出是值的拷貝粥烁,ES6模塊輸出是值的引用(引用時(shí)可能修改到模塊的值)

CommonJS是運(yùn)行時(shí)加載贤笆,ES6模塊是編譯時(shí)加載

ES6 Module是ES6中規(guī)定的模塊體系,相比上面提到的規(guī)范页徐, ES6 Module有更多的優(yōu)勢(shì)苏潜,ES6模塊化的特點(diǎn):

靜態(tài)加載,編譯時(shí)確定依賴關(guān)系

1变勇、自動(dòng)運(yùn)行于嚴(yán)格模式之下

2恤左、export關(guān)鍵字導(dǎo)出

3、import關(guān)鍵字導(dǎo)入

4搀绣、同步飞袋、異步加載均可

CommonJS與ES6 Module的區(qū)別:

1、CommonJS模塊是運(yùn)行時(shí)加載链患,ES6 Module是編譯時(shí)輸出接口

2巧鸭、CommonJS加載的是整個(gè)模塊,將所有的接口全部加載進(jìn)來(lái)麻捻,ES6 Module可以單獨(dú)加載其中的某個(gè)接口纲仍;

3呀袱、CommonJS輸出是值的拷貝,ES6 Module輸出的是值的引用郑叠,被輸出模塊的內(nèi)部的改變會(huì)影響引用的改變夜赵;

4、CommonJS?this指向當(dāng)前模塊乡革,ES6 Module?this指向undefined;

優(yōu)點(diǎn):

容易進(jìn)行靜態(tài)分析

面向未來(lái)的 EcmaScript 標(biāo)準(zhǔn)

缺點(diǎn):

原生瀏覽器端還沒有實(shí)現(xiàn)該標(biāo)準(zhǔn)

全新的命令字寇僧,新版的 Node.js才支持

目前瀏覽器對(duì)ES6 Module兼容還不太好,我們平時(shí)在webpack中使用的export/import沸版,會(huì)經(jīng)過babel轉(zhuǎn)換為CommonJS規(guī)范嘁傀。

具體可以參考:潛入理解ES6-模塊化
? ? ? ? ? ? ? ? ? ? ? ? ?時(shí)光機(jī)-《說說require 和 import 的區(qū)別》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市视粮,隨后出現(xiàn)的幾起案子细办,更是在濱河造成了極大的恐慌,老刑警劉巖馒铃,帶你破解...
    沈念sama閱讀 211,948評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蟹腾,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡区宇,警方通過查閱死者的電腦和手機(jī)娃殖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)议谷,“玉大人炉爆,你說我怎么就攤上這事∥韵” “怎么了芬首?”我有些...
    開封第一講書人閱讀 157,490評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)逼裆。 經(jīng)常有香客問我郁稍,道長(zhǎng),這世上最難降的妖魔是什么胜宇? 我笑而不...
    開封第一講書人閱讀 56,521評(píng)論 1 284
  • 正文 為了忘掉前任耀怜,我火速辦了婚禮,結(jié)果婚禮上桐愉,老公的妹妹穿的比我還像新娘财破。我一直安慰自己,他們只是感情好从诲,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評(píng)論 6 386
  • 文/花漫 我一把揭開白布左痢。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪俊性。 梳的紋絲不亂的頭發(fā)上略步,一...
    開封第一講書人閱讀 49,842評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音定页,去河邊找鬼纳像。 笑死,一個(gè)胖子當(dāng)著我的面吹牛拯勉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播憔购,決...
    沈念sama閱讀 38,997評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼宫峦,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了玫鸟?” 一聲冷哼從身側(cè)響起导绷,我...
    開封第一講書人閱讀 37,741評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎屎飘,沒想到半個(gè)月后妥曲,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,203評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡钦购,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評(píng)論 2 327
  • 正文 我和宋清朗相戀三年檐盟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片押桃。...
    茶點(diǎn)故事閱讀 38,673評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡葵萎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出唱凯,到底是詐尸還是另有隱情羡忘,我是刑警寧澤,帶...
    沈念sama閱讀 34,339評(píng)論 4 330
  • 正文 年R本政府宣布磕昼,位于F島的核電站卷雕,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏票从。R本人自食惡果不足惜漫雕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望纫骑。 院中可真熱鬧蝎亚,春花似錦、人聲如沸先馆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至梅惯,卻和暖如春宪拥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背铣减。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工她君, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人葫哗。 一個(gè)月前我還...
    沈念sama閱讀 46,394評(píng)論 2 360
  • 正文 我出身青樓缔刹,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親劣针。 傳聞我的和親對(duì)象是個(gè)殘疾皇子校镐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評(píng)論 2 349