JS模塊化

一等浊、函數(shù)的Rest參數(shù)和擴展
二腮郊、Promise使用
三、modules.exports和ES6 import/export的使用
四凿掂、AMD伴榔、CMD纹蝴、CommonJS和ES6對比
1)為什么要對JS進行模塊化?

參考:https://www.imooc.com/article/20057

階段一:無模塊化

????????js最初的作用僅僅是為了驗證表單踪少,后來會添加一些動畫塘安,但是這些js代碼很多在一個文件中就可以完成了,所以我們只需要在HTML文件中添加一個script標簽援奢,后來隨著前端復雜度提高兼犯,為了能夠提高項目代碼的可讀性、可擴展性等集漾,我們的js文件逐漸多了起來切黔,不再是一個js文件就能解決的了,而是把每一個js文件當做一個模塊具篇,這時引入js文件的方式如下:

<script src="jquery.js"></script>   
<script src="jquery_scroller.js"></script>   
<script src="main.js"></script>   
<script src="other1.js"></script>   
<script src="other2.js"></script>   
<script src="other3.js"></script>

????????即簡單的將所有的js文件統(tǒng)統(tǒng)放在一起纬霞,但是這些文件的順序還不能出錯,比如jquery需要先引入驱显,才能引入jquery插件诗芜,才能在其他的文件中使用jquery;
????????優(yōu)點:相比于使用一個js文件埃疫,這種多個js文件實現(xiàn)最簡單的模塊化的思想是進步的伏恐;
????????缺點:污染全局作用域,因為每個模塊都是暴露在全局的栓霜,簡單的使用翠桦,會導致全局變量名沖突,當然我們也可以使用命名空間的方式來解決胳蛮,對于大型項目销凑,各種js很多,開發(fā)人員必須手動解決模塊和代碼庫的依賴關系仅炊,后期維護成本較高闻鉴,依賴關系不明顯,不利于維護茂洒,比如main,js需要使用jquery,但是從上面的文件中瓶竭,我們是看不出來的督勺,如果jquer忘記了,就會報錯斤贰;

階段二:CMD規(guī)范

????????CommonJS是一個js模塊化的規(guī)范智哀,該規(guī)范最初是用在服務器端的node的,前端的webpack也是對CommonJS原生支持的荧恍;根據(jù)這個規(guī)范瓷叫,每一個文件就是一個模塊屯吊,其內(nèi)部定義的變量是屬于這個模塊的,不會對外暴露摹菠,也就是說不會污染全局變量盒卸;
????????CommonJS的核心思想是通過require方法來同步加載所要依賴的其他模塊,然后通過exports或者modules.exports來導出需要暴露的接口次氨,如下:

// a.js 
var x = 5; 
var addX = function (value) { return value + x; }; 
module.exports.x = x; 
module.exports.addX = addX;

????????這里的a.js就是一個CommonJS規(guī)范的模塊了蔽介,這里的module就代表了這個模塊,module的exports屬性就是對外暴露的接口煮寡,可以對外導出外部可以訪問的變量虹蓄,比如這里的x和addX;
????????exports是對module.exports的引用幸撕,比如我們可以認為在一個模塊的頂部有這句代碼:exports = module.exports薇组,所以我們不能直接給exports賦值,比如number坐儿、function等律胀,然后我們就可以在其他模塊中引入這個模塊并使用了;

vara = require('./a.js'); 
console.log(example.x); // 5 
console.log(example.addX(1)); // 6

????????這里的require就會獲取到a.js所暴露的module.exports變量挑童,然后就可以使用其暴露的x和addX了累铅。
????????優(yōu)點:CommonJS規(guī)范在服務器端率先完成了JavaScript的模塊化,解決了依賴站叼、全局變量污染的問題娃兽,這也是js運行在服務器端的必要條件。
????????缺點:此文主要是瀏覽器端js的模塊化尽楔, 由于 CommonJS 是同步加載模塊的投储,在服務器端,文件都是保存在硬盤上阔馋,所以同步加載沒有問題玛荞,但是對于瀏覽器端,需要將文件從服務器端請求過來呕寝,那么同步加載就不適用了勋眯,所以,CommonJS是不適用于瀏覽器端的下梢。

階段三: AMD規(guī)范

????????之前提到: CommonJS規(guī)范加載模塊是同步的客蹋,也就是說,只有加載完成孽江,才能執(zhí)行后面的操作讶坯。AMD規(guī)范則是非同步加載模塊,允許指定回調(diào)函數(shù)岗屏。由于Node.js主要用于服務器編程辆琅,模塊文件一般都已經(jīng)存在于本地硬盤漱办,所以加載起來比較快,不用考慮非同步加載的方式婉烟,所以CommonJS規(guī)范比較適用娩井。但是,如果是瀏覽器環(huán)境隅很,要從服務器端加載模塊撞牢,這時就必須采用非同步模式,因此瀏覽器端一般采用AMD規(guī)范叔营。而AMD規(guī)范的實現(xiàn)屋彪,就是大名鼎鼎的require.js了。
????????AMD標準中绒尊,定義了下面兩個API:

   1.require([module], callback)
   2. define(id, [depends], callback)

????????即通過define來定義一個模塊畜挥,然后使用require來加載一個模塊。 并且婴谱,require還支持CommonJS的模塊導出方式蟹但。
????????定義alert模塊:

define(function () {
    var alertName = function (str) {
      alert("I am " + str);
    }
    var alertAge = function (num) {
      alert("I am " + num + " years old");
    }
    return {
      alertName: alertName,
      alertAge: alertAge
    };
  });

????????引入模塊:

require(['alert'], function (alert) {
  alert.alertName('JohnZhu');
  alert.alertAge(21);
});

????????但是,在使用require.js的時候谭羔,我們必須要提前加載所有的依賴华糖,然后才可以使用,而不是需要使用時再加載瘟裸。
????????優(yōu)點:適合在瀏覽器環(huán)境中異步加載模塊客叉。可以并行加載多個模塊话告。
????????缺點:提高了開發(fā)成本兼搏,并且不能按需加載,而是必須提前加載所有的依賴沙郭。

階段四:CMD規(guī)范

????????CMD規(guī)范是阿里的玉伯提出來的佛呻,實現(xiàn)js庫為sea.js。 它和requirejs非常類似病线,即一個js文件就是一個模塊吓著,但是CMD的加載方式更加優(yōu)秀,是通過按需加載的方式送挑,而不是必須在模塊開始就加載所有的依賴夜矗。如下:

define(function(require, exports, module) {
  var $ = require('jquery');
  var Spinning = require('./spinning');
  exports.doSomething = ...
  module.exports = ...
})

????????優(yōu)點:同樣實現(xiàn)了瀏覽器端的模塊化加載;可以按需加載让虐,依賴就近。
????????缺點:依賴SPM打包罢荡,模塊的加載邏輯偏重赡突。

????????其實对扶,這時我們就可以看出AMD和CMD的區(qū)別了,前者是對于依賴的模塊提前執(zhí)行惭缰,而后者是延遲執(zhí)行浪南。 前者推崇依賴前置,而后者推崇依賴就近漱受,即只在需要用到某個模塊的時候再require络凿。 如下:

// AMD
define(['./a', './b'], function(a, b) {  // 依賴必須一開始就寫好  
   a.doSomething()    
   // 此處略去 100 行    
   b.doSomething()    
   ...
});
// CMD
define(function(require, exports, module) {
   var a = require('./a')   
   a.doSomething()   
   // 此處略去 100 行   
   var b = require('./b') 
   // 依賴可以就近書寫   
   b.doSomething()
   // ... 
});
階段五: ES6模塊化

????????之前的幾種模塊化方案都是前端社區(qū)自己實現(xiàn)的,只是得到了大家的認可和廣泛使用昂羡,而ES6的模塊化方案是真正的規(guī)范絮记。 在ES6中,我們可以使用 import 關鍵字引入模塊虐先,通過 export 關鍵字導出模塊怨愤,功能較之于前幾個方案更為強大,也是我們所推崇的蛹批,但是由于ES6目前無法在瀏覽器中執(zhí)行撰洗,所以,我們只能通過babel將不被支持的import編譯為當前受到廣泛支持的 require腐芍。
????????雖然目前import和require的區(qū)別不大差导,但是還是推薦使用使用es6,因為未來es6必定是主流猪勇,對于代碼的遷移成本還是非常容易的设褐。 如:

  import store from '../store/index'
  import {mapState, mapMutations, mapActions} from 'vuex'
  import axios from '../assets/js/request'
  import util from '../utils/js/util.js'

  export default {
    created () {
      this.getClassify(); 
      this.RESET_VALUE();
      console.log('created' ,new Date().getTime());
    }
總結(jié)

???????1)AMD是RequireJs在推廣過程中對模塊定義的規(guī)范化產(chǎn)出,依賴前置埠对;
???????2)CMD是SeaJs在推廣過程中對模塊化定義的規(guī)范化產(chǎn)出络断,依賴就近,淘寶團隊项玛;
???????3)CommonJs規(guī)范貌笨,modules.exports,前端瀏覽器不支持CommonJs規(guī)范襟沮,Node端使用锥惋;
???????4)ES6特性,export/import开伏;
???????5)2009年膀跌,ES5出現(xiàn),例如foreach固灵,Object.keys捅伤,Object.create和JSON標準;

參考文檔:http://yijiebuyi.com/blog/7c8ffb3a58657e01e80f3bdc747473d2.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末巫玻,一起剝皮案震驚了整個濱河市丛忆,隨后出現(xiàn)的幾起案子祠汇,更是在濱河造成了極大的恐慌,老刑警劉巖熄诡,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件可很,死亡現(xiàn)場離奇詭異,居然都是意外死亡凰浮,警方通過查閱死者的電腦和手機我抠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來袜茧,“玉大人菜拓,你說我怎么就攤上這事”怪埽” “怎么了尘惧?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長递递。 經(jīng)常有香客問我喷橙,道長,這世上最難降的妖魔是什么登舞? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任贰逾,我火速辦了婚禮,結(jié)果婚禮上菠秒,老公的妹妹穿的比我還像新娘疙剑。我一直安慰自己,他們只是感情好践叠,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布言缤。 她就那樣靜靜地躺著,像睡著了一般禁灼。 火紅的嫁衣襯著肌膚如雪管挟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天弄捕,我揣著相機與錄音僻孝,去河邊找鬼。 笑死守谓,一個胖子當著我的面吹牛穿铆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播斋荞,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼荞雏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起讯檐,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤羡疗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后别洪,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡柳刮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年挖垛,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秉颗。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡痢毒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蚕甥,到底是詐尸還是另有隱情哪替,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布菇怀,位于F島的核電站凭舶,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏爱沟。R本人自食惡果不足惜帅霜,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望呼伸。 院中可真熱鬧身冀,春花似錦、人聲如沸括享。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽褥紫。三九已至窖梁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間澳叉,已是汗流浹背隙咸。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留成洗,地道東北人五督。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像瓶殃,于是被迫代替她去往敵國和親充包。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

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

  • 什么是模塊化家浇? 簡單理解:將各個功能封裝為獨立的模塊本砰,當需要某個功能時,只需要加載相應的模塊即可 為什么出現(xiàn)模塊化...
    放風箏的小小馬閱讀 835評論 0 6
  • 模塊 函數(shù)式 模塊是實現(xiàn)特定功能的文件钢悲,將多個函數(shù)編寫在同一個文件中就構(gòu)成了一個模塊点额,加載文件即可調(diào)用文件中的函數(shù)...
    JunChow520閱讀 453評論 0 1
  • 歷史上JavaScript一直沒有模塊體系,在其他高級語言中莺琳,Java有類文件还棱,Python有import機制,R...
    還是那個西瓜閱讀 261評論 0 1
  • requirejs是一個JavaScript文件和模塊加載器惭等。requireJS允許你把你的javascript代...
    GQ1994閱讀 2,195評論 0 58
  • 真冷啊… 窗子連窗紙都沒有珍手,冷風一陣陣灌進來,身上的破氈毯怎么也蓋不全辞做,手腳都麻了琳要,也不知道被凍的還是被吹的。身下...
    純棉有喜閱讀 392評論 1 1