本文可能不涉及一些基礎概念,好比什麼是模塊,對每種方案也沒有都作詳細的解釋(若是解釋的話,每一個都值得一篇文章),準備和落實這篇文章主要是有兩方面緣由。javascript
CommonJS
,seaJS
,CMD
,AMD
,UMD
,Browserify
,RequireJS
,知道他們和js模塊有關,但具體是什麼關係,js模塊化應該用哪一個的倒是不知道。綜上兩點,就是對JS的模塊不熟悉致使的。前端
對JS模塊化有一個直面的瞭解,並能捋清楚各個規範之間的之間的聯繫,再遇到這些名詞不會再有它認識我,我不認識它
的感受java
首先來講爲何須要模塊化,這個你們內心應該都有一兩個答案,好比避免命名衝突啊,全局變量過多啊,依賴很差管理啊等等等等。總得來講模塊化大方向上有幾個好處。node
整體上模塊化基本上是一個百利無一害的實現jquery
開始JS沒有模塊的概念,所以致使了不少問題,好比命名衝突,好比:webpack
var origin = 100;
....其餘代碼
var origin = 1232;
....其餘代碼
console.log(origin)//目標是讓它輸出100,但實際會輸出1232,由於後來的命名覆蓋
複製代碼
還有依賴問題,好比a.js依賴了b.js,那麼下載時必須是先下載b,在下載a,順序必定不能錯。web
爲了解決這些沒有模塊帶來的問題,前輩們提出了使用IIFE來模仿模塊,以下:gulp
(function(){
var name = 'wingtao;
var sayHello = function (){
console.log('hello '+name);
}
sayHello(); // hello wingtao
})()
複製代碼
上面利用當即執行函數模擬了一個模塊,該模塊中的變量外界沒法訪問,避免了命名衝突的問題,jQuery就用了這種方式,api
(function(global){
global.jquery = ...
})(window);
複製代碼
但仍是沒有徹底實現模塊化,如對模塊依賴的管理、如何將api暴露出來而不污染全局環境瀏覽器
CommonJS社區首先提出了模塊化的規範CommonJS,因此CommonJS是一個規範!在node上只須要簡單的require和exports就能夠實現模塊的導入和導出,以下:
a.js
exports.add = function(a,b){
return a+b;
}
b.js
var add = require('a.js').add;
console.log(add(1,2))//3
複製代碼
看起來很是棒!並且nodeJS模塊實現了這種規範,意味着在node中能夠直接使用這種方式。
既然服務端能實現了這種模塊化的規範,瀏覽器上對此也是很是迫切的,天然也是想要實現這塊,可是直接拿來用是有一些問題,
所以若是想在瀏覽器上使用CommonJS是須要改造的,對此人們分紅了幾派,一派是認爲仍是按照CommonJS規範來,只是加上函數包裹和異步加載,在瀏覽器上能執行就好了;一派認爲CommonJS不適合瀏覽器端,須要一個新的規範;第三方是個「和稀泥」的,認爲CommonJS和從新改革都有可取之處,因此各取所長。
其中第一派堅持使用CommonJS的作出了瀏覽器端的實現Browserify,名字也很形象,Browserify能夠將node端模塊文件轉換爲瀏覽器可識別的模塊文件。因此Browserify是CommonJS在瀏覽器端的實現
AMD(規範)其實就是上面說的第二派,就是拋棄CommonJS,提出新的可異步加載的模塊規範。AMD最大的特色即是能夠異步加載模塊,它的實現是RequireJS,編寫時像這樣:
define(['myModule', 'myOtherModule'],function(myModule, myOtherModule) {
console.log(myModule.hello());
});
複製代碼
過程是先加載依賴myModule,myOtherModule(後臺不阻塞的方式加載),加載完成後執行回調函數,其中回調函數的參數即是已經加載完成的模塊。其實AMD仍是有不少問題的,好比define的時候全部依賴要挨個寫一遍,好比無論如今用不用的到都會把依賴先下載下來,不過這些問題AMD都有優化,這裏不提。
UMD全稱是Universal Module Definition,目的兼容CommonJS和AMD,因此它會作一層判斷,判斷當前環境是瀏覽器仍是node,若是是瀏覽器則使用AMD,node環境使用CommonJS方式,UMD實現了兩種環境的兼容,但同時也致使了十分臃腫,肉眼觀察實在有點費勁。
提起CMD,不怕被笑話,我以前還覺得和CommonJS是同一個東東呢😂。seaJS是阿里前端工程師玉伯作出來的,並提出了CMD,CMD吸收了AMD和CommonJS二者的優勢,融合了百家之長(但好像只在國內有影響,國外影響有限),因此CMD是規範而seajs是它的實現。
以上說的種種方式都是由於ECMA缺少官方的模塊規範纔出來的,既然對模塊化的需求這麼旺盛,官方在ES2015(ES6)裏也就提出了官方的模塊化方案,主要使用import和export,用法很是簡單,並且它和以前的方案的區別除了它是官方提出而且寫法簡單以外,還有重要的一點就是它是靜態解析的,什麼是靜態解析呢?另開一篇文章再講,不過這個特性能夠帶來不少優化,如tree-shaking。ES6模塊機制理論上是瀏覽器原生支持的,但實際上如今支持度還不夠,這個你們應該也能理解,不過在將來應該可能就能在瀏覽器中直接加載導出模塊了,
這些工具其實和上面講的模塊規範已經不是一個維度的事情了,上面說的是模塊化,這些是一些能夠打包的工具,打包什麼呢?模塊!這就是他們之間的聯繫了。就不展開講了,這是三個東西太多了。
簡單總結一下上面講的東西,其實就是講了下js模塊的幾個方案,每一個方案都有本身的規範,然而只有規範還不行,須要有實現來支持它,因此總得來講就是:
環境 | 規範 | 實現 |
---|---|---|
node | CommonJS | nodejs 模塊 |
瀏覽器 | CommonJS | Browserify |
瀏覽器 | AMD | RequireJS |
瀏覽器 | UMD | 👆二者 |
瀏覽器 | CMD | SeaJS |
寫下來這些就是但願本身能對js模塊化有一個較爲全面的瞭解,面對這些名詞再也不默認,並瞭解他們之間的關係。
文章倉促,有不足之處但願多多指出。
若是你看完對你有些許的幫助,那是意外之喜😊。