模塊化開發(fā): CommonJS / AMD / CMD / ES6

模塊化的開發(fā)方式可以提高代碼復(fù)用率,方便進(jìn)行代碼的管理袒餐。通常一個(gè)文件就是一個(gè)模塊飞蛹,有自己的作用域,只向外暴露它的接口灸眼。目前流行的js模塊化規(guī)范有CommonJS卧檐、AMD、CMD以及ES6的模塊系統(tǒng)焰宣。

  • <script>標(biāo)簽

    • 全局作用域下容易造成變量沖突
    • 文件只能按照<script>的書寫順序進(jìn)行加載
    • 開發(fā)人員必須主觀解決模塊和代碼庫的依賴關(guān)系
    • 在大型項(xiàng)目中各種資源難以管理霉囚,長期積累的問題導(dǎo)致代碼庫混亂不堪
  • CommonJS

    • 定義的模塊分為: 模塊引用(require) / 模塊輸出(exports) / 模塊標(biāo)識(shí)(module)
    • 是更偏向于服務(wù)器端的規(guī)范。NodeJS采用了這個(gè)規(guī)范匕积。CommonJS的一個(gè)模塊就是一個(gè)腳本文件盈罐。require命令第一次加載該腳本時(shí)就會(huì)執(zhí)行整個(gè)腳本榜跌,然后在內(nèi)存中生成一個(gè)對(duì)象。
    • CommonJS是同步加載模塊盅粪,這對(duì)于服務(wù)器端不是一個(gè)問題钓葫,因?yàn)樗械哪K都放在本地硬盤。等待模塊時(shí)間就是硬盤讀取文件時(shí)間票顾,很小础浮。但是,對(duì)于瀏覽器而言奠骄,它需要從服務(wù)器加載模塊豆同,涉及到網(wǎng)速,代理等原因戚揭,一旦等待時(shí)間過長诱告,瀏覽器處于”假死”狀態(tài)。所以在瀏覽器端民晒,不適合于CommonJS規(guī)范精居。
      {
          id:'...',
          exports: { ... },
          loaded: true,
          ...
      }
      /* id是模塊名,exports是該模塊導(dǎo)出的接口潜必,loaded表示模塊是否加載完畢靴姿。
      此外還有很多屬性,這里省略了磁滚。
      以后需要用到這個(gè)模塊時(shí)佛吓,就會(huì)到exports屬性上取值。
      即使再次執(zhí)行require命令垂攘,也不會(huì)再次執(zhí)行該模塊维雇,而是到緩存中取值。*/
      
      // 例:
      math.jsexports.add = function(a, b) {
          return a + b;
      }
      var math = require('math');
      math.add(2, 3);
      
  • AMD (Asynchronous Module Definition) 異步模塊定義

    • AMD是RequireJs在推廣過程中對(duì)模塊定義的規(guī)范化產(chǎn)出
    • 這里異步指的是不堵塞瀏覽器其他任務(wù)(dom構(gòu)建晒他,css渲染等)吱型,而加載內(nèi)部是同步的(加載完模塊后立即執(zhí)行回調(diào))。
    • 依賴前置
      /* AMD也采用require命令加載模塊陨仅,但是不同于CommonJS津滞,它要求兩個(gè)參數(shù):*/
      require([module], callback);
       /* 第一個(gè)參數(shù)[module],是一個(gè)數(shù)組灼伤,里面的成員是要加載的模塊触徐,callback是加載完成后的回調(diào)函數(shù)。
      如果將上述的代碼改成AMD方式:*/
          require(['math'], function(math) {
              math.add(2, 3);
          })
      //其中狐赡,回調(diào)函數(shù)中參數(shù)對(duì)應(yīng)數(shù)組中的成員(模塊)撞鹉。
      //修改為define的寫法:
      // math.js
      define(['dependenceModule'], function(dependenceModule)
        var add = function(x, y) {
          return x + y;
        }
        return  {
          add: add
        }
      })
      /* 當(dāng)require()函數(shù)加載math模塊的時(shí)候,就會(huì)先加載dependenceModule模塊。
      當(dāng)有多個(gè)依賴時(shí)孔祸,就將所有的依賴都寫在define()函數(shù)第一個(gè)參數(shù)數(shù)組中隆敢。
      所以說AMD是依賴前置的发皿。這不同于CMD規(guī)范崔慧,它是依賴就近的。*/
      
  • CMD (Common Module Definition)

    • Seajs推崇的規(guī)范
    • 依賴就近穴墅,用的時(shí)候再require, 推崇 as lazy as possible(盡可能的懶加載惶室,也稱為延遲加載,即在需要的時(shí)候才加載)玄货。
      // 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();
      })
      
    • CMD和AMD的區(qū)別
      • AMD和CMD都是用difine和require的異步加載
      • 但是CMD標(biāo)準(zhǔn)傾向于在使用過程中提出依賴皇钞,就是不管代碼寫到哪突然發(fā)現(xiàn)需要依賴另一個(gè)模塊,那就在當(dāng)前代碼用require引入就可以了松捉,規(guī)范會(huì)幫你搞定預(yù)加載
      • AMD標(biāo)準(zhǔn)讓你必須提前在頭部依賴參數(shù)部分寫好(沒有寫好夹界? 倒回去寫好咯)。
  • ES6 模塊

    • ES6 模塊不是對(duì)象隘世,無法引用模塊本身可柿。而是通過export命令顯式指定輸出的代碼,再通過import命令輸入丙者。
    • ES6 可以在編譯時(shí)就完成模塊加載复斥,效率要比 CommonJS 模塊的加載方式高
    • 頂層的this指向undefined
    • 瀏覽器加載 ES6 模塊,也使用<script>標(biāo)簽械媒,但是要加入type="module"屬性目锭。瀏覽器對(duì)于帶有type="module"的<script>,都是異步加載纷捞,不會(huì)造成堵塞瀏覽器痢虹。<script type="module" src="./foo.js"></script>
  • import和require的區(qū)別

    • vue模塊引入使用import,node模塊引入使用require
    • require 是 AMD規(guī)范引入方式主儡,import是es6的一個(gè)語法標(biāo)準(zhǔn)奖唯,如果要兼容瀏覽器的話必須轉(zhuǎn)化成es5的語法
    • 通過require引入基礎(chǔ)數(shù)據(jù)類型時(shí),屬于復(fù)制該變量缀辩。通過require引入復(fù)雜數(shù)據(jù)類型時(shí)臭埋,數(shù)據(jù)淺拷貝該對(duì)象
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市臀玄,隨后出現(xiàn)的幾起案子瓢阴,更是在濱河造成了極大的恐慌,老刑警劉巖健无,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荣恐,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)叠穆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門少漆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人硼被,你說我怎么就攤上這事示损。” “怎么了嚷硫?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵检访,是天一觀的道長。 經(jīng)常有香客問我仔掸,道長脆贵,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任起暮,我火速辦了婚禮卖氨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘负懦。我一直安慰自己筒捺,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布密似。 她就那樣靜靜地躺著焙矛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪残腌。 梳的紋絲不亂的頭發(fā)上村斟,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音抛猫,去河邊找鬼蟆盹。 笑死,一個(gè)胖子當(dāng)著我的面吹牛闺金,可吹牛的內(nèi)容都是我干的逾滥。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼败匹,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼寨昙!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起掀亩,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤舔哪,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后槽棍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體捉蚤,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡抬驴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了缆巧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片布持。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖陕悬,靈堂內(nèi)的尸體忽然破棺而出题暖,到底是詐尸還是另有隱情,我是刑警寧澤墩莫,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布芙委,位于F島的核電站逞敷,受9級(jí)特大地震影響狂秦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜推捐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一裂问、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧牛柒,春花似錦堪簿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蛾魄,卻和暖如春虑瀑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背滴须。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國打工舌狗, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人扔水。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓痛侍,卻偏偏與公主長得像,于是被迫代替她去往敵國和親魔市。 傳聞我的和親對(duì)象是個(gè)殘疾皇子主届,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355