原文參考 玉伯 大神些的,我整理了一下。
咱們今天主題說下前端模組化發展的歷史,主要是針對AMD CMD 的發展,這兩個東西是一種規範,他們實際產物是AMD是RequireJS,CMD的產物是seajs,他們的出現都是在COMMONjs基礎上發展而來的,那咱們得先說說COMMONjs。
COMMONJS
大概 09 年 – 10 年期間,CommonJS 社群大牛雲集。 CommonJS 原來叫 ServerJS,推出 Modules/1.0 規格後,在Node.js 環境下取得了很不錯的實作。 09年下半年這群牛逼愛折騰的大神們想把 ServerJS 的成功經驗進一步推廣到瀏覽器端,於是將社區改名叫 CommonJS,同時激烈爭論 Modules 的下一版規範。分歧和衝突由此誕生,逐步形成了三大流派:Modules/1.x (完全基於1.0的功能,只是增加一個轉換功能),Modules/Async ,Modules/2.0 。
Modules/1.x 類型:這個觀點覺得 1.x 規格已經夠用,只要移植到瀏覽器端就好。要做的是新增 Modules/Transport 規範,也就是在瀏覽器上運作前,先透過轉換工具將模組轉換為符合 Transport 規範的程式碼。現在值得關注的有兩個實作:component 和es6 module。
Modules/Async 類型:這個觀點覺得瀏覽器有自己的特徵,不應該直接用 Modules/1.x 規格。這個觀點下的典型代表是 AMD 規範及其實作 RequireJS。這個稍後再細說。
Modules/2.0 類型:這個觀點覺得瀏覽器有自身的特徵,不應該直接用 Modules/1.x 規範,但應該盡可能與 Modules/1.x 規範保持一致。這個觀點下的典型代表是 BravoJS 和 FlyScript 的作者。 BravoJS 作者對 CommonJS 的社群的貢獻很大。 FlyScript 的作者提出了 Modules/Wrappings 規範,這是 CMD 規範的前身。可惜的是 BravoJS 太學院派,FlyScript 後來做了自我閹割,將整個網站(flyscript.org)下線了。這個故事有點悲壯,就不細講了。
上面是產生的三大流派,也就是說Modules/2.0開始的產物都無疾而終了,而當時Modules/1.x 規範的 ES6還不成熟,在後來就是以Modules/Async 為規範的RequireJS 發展的很火熱。
但是AMD 的RequireJS 的執行時機有異議,模組書寫風格有爭議,一直沒有被CommonJS社群認同,咱們詳細的說下這兩個點:
AMD 裡提前下載a .js 是瀏覽器的限制,沒辦法做到同步下載,這個社群都認可,但執行,AMD 裡是提前執行,二在基礎Modules/1.0 規範裡是第一次require的時候才執行。這個差異很多人不能接受,包括持有Modules/2.0 觀點的人也不能接受AMD的這個觀點,這個差異,也導致實質上Node 的模組與AMD 模組是無法共享的,存在潛在衝突;
另外一個就是:模組書寫風格有爭議
AMD 風格下,透過參數傳入依賴模組,破壞了就近聲明原則,就近原則就是在用的時候才會用,而不需要事先聲明模組。最後,AMD 從CommonJS 社區獨立了出去,單獨成為了AMD 社區,後來你們就知道了 RequireJS 特別火!
其實這個時候脫離了CommonJS 社區的AMD 規範,實質上演化成了RequireJS 的附屬品,後來RequireJS 社群有很多人反饋想用require 的方式,最後RequireJS 作者妥協,才有了這個半殘的支持。 (注意這個是偽支持,背後依舊是 AMD 的運作邏輯,例如提前執行)AMD 的流行,很大程度上取決於 RequireJS 作者的推廣,AMD 規範的演進,離不開 RequireJS。
BravoJS 的作者 Wes Garland 有著深厚的程式功底,在 CommonJS 社群也非常受人尊敬。但 BravoJS 本身非常學院派,是為了論證 Modules/2.0-draft 規範而寫的一個項目。學院派在實用派的 RequireJS 面前不堪一擊,現在基本上只留存了一些美好的回憶。
這時,Modules/2.0 陣營也有一個實戰派:FlyScript,提出了非常簡潔的Modules/Wrappings 規範:這個簡潔的規範考慮了瀏覽器的特殊性,同時也盡可能兼容了Modules/ 1.0 規範。悲催的是,FlyScript 在推出正式版和官網之後,RequireJS 當時正直紅火。期間 FlyScript 作者 和 RequireJS 作者 James Burke 有過一些爭論。再後來,FlyScript 作者做了自我閹割,將GitHub 上的專案和官網都清空了,官網上當時留了一句話,模糊中記得是:我會回來的,帶著更好的東西。
這中間究竟發生了什麼,不得而知。後來玉伯寄email給 FlyScript作者 詢問,對方給了兩點挺讓我尊重的理由,大意是:
我並非前端出身,RequireJS 的作者 James Burke 比我更懂瀏覽器。
我們應該協同起來推動一個社群的發展,即使它不是你喜歡的。
這兩句話對玉伯影響很大。也是那之後,開始仔細研究 RequireJS,並透過電子郵件等方式給 RequireJS 提出不少建議。再後來,在實際使用 RequireJS 的過程中,遇到了許多坑。那時 RequireJS 雖然很火,但真不夠完善。期間也在尋思著FlyScript 離開時的那句話:「我會回來的,帶著更好的東西」
玉伯說我沒FlyScript 的作者那麼偉大,在不斷給RequireJS 提建議,但不斷不被採納後,開始萌生了自己寫一個loader 的念頭。
這就是 SeaJS。 SeaJS 借鏡了 RequireJS 的不少東西,例如將 FlyScript 中的 module.declare
改名為 define
等。 SeaJS 更來自 Modules/2.0 的觀點,但盡可能去掉了學院派的東西,加入了不少實戰派的理念。這個就是CMD的間接產物,SeaJs。
好了基本的歷史都說完了,不知道我說的能不能讓大家聽明白,大概的總結下就是最先有的COMMONJS,因為COMMONJS用於是服務端的,不能直接用於瀏覽器,對於怎樣將這個規範用在瀏覽器,新生事物必然有爭論,也的就產生了不同的觀念和論點,所以也就出現了適用於瀏覽器的AMD規範,CMD規範,AMD的存在的一些問題不被COMMONJS社區認同,最後獨立運作,當然RequireJS也確實也大火了一段時間,後來CMD的產物seajs被玉伯開發出來。
到現在來看這兩個產物估計是已經過時了,當然還有在用的,畢竟後來的webpack es6的發展勢不可擋,webpakc對三種規範完全支持,後面的時間還會給大家分享下webpack的一些知識,對於前端模組化發展史就說到這裡,對於初學前端的人了解歷史發展還是很有必要的。其實這原文是玉伯寫的,我只是更改了下變成了我自己的化,方便大家理解,大家也可以去搜下關於前端模組化歷史那點事,這裡沒有說為什麼需要模組化大家也可以先了解下,帶著問題去學習才會學的更快。
以上是前端模組化的發展史的詳細內容。更多資訊請關注PHP中文網其他相關文章!