精讀《js 模塊化生長》

此次是前端精讀期刊與人人第一次正式謀面,我們每周會精讀並剖析多少篇佳構好文,試圖議論出結論性看法。沒錯,我們試圖經由歷程看法的碰撞,爭做無主觀佳構好文的看法首腦。

我是這一期的主持人 —— 黃子毅

本期精讀的文章是:evolutionOfJsModularity

懶得看文章?沒緊要,稍後會附上文章內容概述,同時,更願望能經由歷程瀏覽這一期的精讀,穿插着深切瀏覽原文。

1 弁言

《精讀《js 模塊化生長》》

如今,Javascript 模塊化範例非常輕易、天然,但這個新範例僅實行了2年,就在 4 年前,js 的模塊化還停留在運行時支撐,10 年前,經由歷程後端模版定義、解釋定義模塊依靠。對閱歷過來的人來講,汗青的模塊化體式格局還停留在腦海中,反而新上手的同硯會更快接收當代的模塊化範例。

但為何要相識 Javascript 模塊化生長的汗青呢?因為凡事都有兩面性,相識 Javascript 模塊化範例,有利於我們思考出更好的模塊化計劃,縱觀汗青,從 1999 年最先,模塊化計劃最多保持兩年,就出現了新的替換計劃,比原有的模塊化更清楚、強健,我們不能被當代模塊化體式格局限制住頭腦,因為如今的 ES2015 模塊化計劃間隔宣布也僅僅過了兩年。

2 內容提要

直接定義依靠 (1999): 因為當時 js 文件非常簡樸,模塊化體式格局非常簡樸粗獷 —— 經由歷程全局要領定義、援用模塊。這類定義體式格局與如今的 commonjs 非常神似,區別是 commonjs 以文件作為模塊,而這類要領能夠在任何文件中定義模塊,模塊不與文件關聯。

閉包模塊化形式 (2003): 用閉包體式格局處置懲罰了變量污染題目,閉包內返回模塊對象,只需對外暴露一個全局變量。

模版依靠定義 (2006): 這時刻最先盛行後端模版語法,經由歷程後端語法聚合 js 文件,從而完成依靠加載,說實話,如今 go 言語等模版語法也很盛行這類體式格局,寫後端代碼的時刻不覺得,轉頭看看,照樣掛在可保護性上。

解釋依靠定義 (2006): 險些和模版依靠定義同時出現,與 1999 年計劃差別的,不僅僅是模塊定義體式格局,而是終究以文件為單元定義模塊了,經由歷程 lazyjs 加載文件,同時讀取文件解釋,繼承遞歸加載剩下的文件。

外部依靠定義 (2007): 這類定義體式格局在 cocos2d-js 開闢中普遍運用,个中心頭腦是將依靠抽出零丁文件定義,這類體式格局不利於項目治理,畢竟依靠抽到代碼以外,我是否是得兩端找呢?所以才有經由歷程 webpack 打包為一個文件的體式格局暴力替換為 commonjs 的體式格局出現。

Sandbox形式 (2009): 這類模塊化體式格局很簡樸,暴力,將一切模塊塞到一個 sanbox 變量中,硬傷是沒法處置懲罰明顯爭執題目,畢竟都塞到一個 sandbox 對象里,而 Sandbox 對象也須要定義在全局,存在被掩蓋的風險。模塊化須要保證全局變量只管清潔,現在為止的模塊化計劃都沒有很好的做到這一點。

依靠注入 (2009): 就是人人熟知的 angular1.0,依靠注入的頭腦如今已普遍運用在 react、vue 等盛行框架中。但依靠注入和處置懲罰模塊化題目還差得遠。

CommonJS (2009): 真正處置懲罰模塊化題目,從 node 端逐步發力到前端,前端須要運用構建東西模仿。

Amd (2009): 都是一致時代的產品,這個計劃主要處置懲罰前端動態加載依靠,比擬 commonJs,體積更小,按需加載。

Umd (2011): 兼容了 CommonJS 與 Amd,个中心頭腦是,假如在 commonjs 環境(存在 module.exports,不存在 define),將函數實行效果交給 module.exports 完成 Commonjs,否則用 Amd 環境的 define,完成 Amd。

Labeled Modules (2012): 和 Commonjs 很像了,沒什麼硬傷,但生不逢時,碰上 Commonjs 與 Amd,那隻要被人忘記的份了。

YModules (2013): 既然都出了 Commonjs Amd,文章還列出了此計劃,肯定有其獨到之處。个中心頭腦在於運用 provide 庖代 return,能夠掌握模塊完畢機遇,處置懲罰異步效果;拿到第二個參數 module,修正其他模塊的定義(雖然很有拓展性,但用在項目里是個攪屎棍)。

ES2015 Modules (2015): 就是我們如今的模塊化計劃,還沒有被瀏覽器完成,大部份項目已由歷程 babeltypescript 提早體驗。

3 精讀

本次提出獨到看法的同硯有:流形黃子毅蘇里約camsong楊森淡蒼留影,精讀由此歸結。

從言語層面到文件層面的模塊化

從 1999 年最先,模塊化探究都是基於言語層面的優化,真正的反動從 2009 年 CommonJS 的引入最先,前端最先大批運用預編譯。

這篇文章所供應的模塊化汗青的計劃都是邏輯模塊化,從 CommonJS 計劃最先前端把效勞端的處置懲罰計劃搬過來今後,算是看到規範物理與邏輯一致的模塊化。但今後前端工程不能不引入模塊化構建這一步。恰是這一步給前端開闢無疑帶來了諸多的不方便,尤其是如今我們開闢歷程當中常常為了優化這個東西帶了許多分外的本錢。

從 CommonJS 之前實在都只是封裝,並沒有一套模塊化範例,這個就有些像類與包的觀點。我在10年擺布用的最多的照樣 YUI2,YUI2 是用 namespace 來做模塊化的,但有許多題目沒有處置懲罰,比方多版本共存,因而厥後 YUI3 出來了。

YUI().use('node', 'event', function (Y) {
    // The Node and Event modules are loaded and ready to use.
    // Your code goes here!
});

YUI3 的 sandbox 像極了差不多同時出現的 AMD 範例,但初期 yahoo 在前端圈的影響力照樣很大的,而 requirejs 到 2011 年才降生,因而圈子不是用着 YUI 要不就自身封裝一套 sandbox,內部運用 jQuery。

為何模塊化計劃這麼晚才成型,能夠初期運用的龐雜度都在後端,前端都是非常簡樸邏輯。厥後 Ajax 火了今後,web app 觀點的最先盛行,前端的龐雜度也呈指數級上漲,到本日險些和後端靠近一個量級。工程生長到肯定階段,要出現的必定會出現。
 

前端三劍客的模塊化瞻望

從 js 模塊化生長史,我們還看到了 css html 模塊化方面的嚴峻落伍,如今依靠編譯東西的模塊化加強在未來會被規範所替換。

原生支撐的模塊化,處置懲罰 html 與 css 模塊化題目恰是今後的方向。

再回到 JS 模塊化這個主題,開首也說到是為了構建 scope,實則供應了營業範例規範的輸入輸出的體式格局。但文章中的 JS 的模塊化還不即是前端工程的模塊化,Web 界面是由 HTML、CSS 和 JS 三種言語完成,不論是 CommonJS 照樣 AMD 包含今後的計劃都沒法處置懲罰 CSS 與 HTML 模塊化的題目。

關於 CSS 自身它就是 global scope,因而開闢款式能夠說是喜憂參半。近幾年也出現把 HTML、CSS 和 JS 合併作模塊化的計劃,个中 react/css-modules 和 vue 都為人熟知。固然,這一點照樣非常依靠於 webpack/rollup 等構建東西,讓我們意想到在 browser 端另有許多實質的題目須要推進。

關於 css 模塊化,現在不依靠預編譯的體式格局是 styled-component,經由歷程 js 動態建立 class。而現在 css 也引入了與 js 通訊的機制 與 原生變量支撐。未來 css 模塊化也許多是運行時的,所以現在比較看好 styled-component 的方向。

關於 html 模塊化,小尤近來爆出與 chrome 小組調研 html Modules,假如 html 獲得了瀏覽器,編輯器的模塊化支撐,未來能夠會庖代 jsx 成為最壯大的模塊化、模板言語。

關於 js 模塊化,近來出現的 <script type="module"> 體式格局,雖然還沒有獲得瀏覽器原生支撐,但也是我比較看好的未來趨向,如許就連 webpack 的拆包都不須要了,直接把源代碼傳到效勞器,合營 http2.0 圓滿拋開預編譯的桎梏。

上述三中計劃都不依靠預編譯,離別完成了 html、css、js 模塊化,置信這就是未來。

模塊化規範推進速率依舊遲緩

2015 年提出的規範,在 17 年依舊沒有獲得完成,即便在 nodejs 端。

這幾年 TC39 對言語終究注重起來了,逐步有行動了,但針對模塊規範制訂的速率,與落實都非常遲緩,與 javascript 愈來愈盛行的趨向逐步擺脫。nodejs 至今也沒有完成 ES2015 模塊化範例,一切 jser 都處在構建東西的暗影下。

Http 2.0 對 js 模塊化的推進

js 模塊化定義的再優美,瀏覽器端的支撐粒度永久是瓶頸,http 2.0 恰是斟酌到了這個要素,大力支撐了 ES 2015 模塊化範例。

榮幸的是,模塊化構建未來能夠不再須要。跟着 HTTP/2 盛行起來,請乞降相應能夠并行,一次銜接許可多個要求,關於前端來講宣布不再須要在開闢和上線時再做編譯這個行動。

幾年前,模塊化險些是每一個盛行庫必造的輪子(YUI、Dojo、Angular),大牛們自身爽的同時實在造成了社區的破裂,很難積聚。有了 ES2015 Modules 今後,JS 開闢者終究能夠像 Java 最先者十年前一樣運用一致的體式格局興奮的相互援用模塊。

不過 ES2015 Modules 也只是處置懲罰了開闢的題目,因為瀏覽器的特殊性,照樣要經由煩瑣打包的歷程,等 Import,Export 和 HTTP 2.0 被主流瀏覽器支撐,那時刻才是完全的模塊化。

Http 2.0 后就不須要構建東西了嗎?

看到人人基礎都提到了 HTTP/2,對這項手藝處置懲罰前端模塊化及資本打包等工程題目抱有非常大的期待。許多人也以為 HTTP/2 提高后,基礎就沒有 Webpack 什麼事情了。

不過 Webpack 作者 @sokra 在他的文章 webpack & HTTP/2 里提到了一個新的 Webpack 插件 AggressiveSplittingPlugin。簡樸的說,這款插件就是為了充分應用 HTTP/2 的文件緩存才能,將你的營業代碼自動拆分紅多少個數十 KB 的小文件。後續若个中恣意一個文件發生變化,能夠保證其他的小 chunck 不須要從新下載。

可見,縱然不停的有新手藝出現,也依舊須要配套的東西來將前端工程題目處置懲罰計劃推向極致。

模塊化是大型項目標銀彈嗎?

只需遵照了最新模塊化範例,就能夠使項目具有最好的可保護性嗎? Js 模塊化的目標是支撐前端日趨上升的龐雜度,但絕不是唯一的處置懲罰計劃。

剖析下 JavaScript 為何沒有模塊化,為何又須要模塊化:這個 95 年被設想出來的時刻,言語的開闢者基礎沒有想到它會云云的大放異彩,也沒有將它設想成一種模塊化言語。根據文中的說法,99 年也就是 4 年後最先出現了模塊化的需求。假如只要幾行代碼用模塊化是扯,初始的 web 開闢營業邏輯都寫在 server 端,js 的作用小之又小。而如今 spa 都出現了,險些一切的襯着邏輯都在前端,假如照樣沒有模塊化的構造,開闢歷程會愈來愈難,保護也是更痛楚。

文中已細緻說清楚明了模塊化的生長和好壞,這裏不準備做過量的議論。我想說的是,在模塊化今後另有一個模塊間耦合的題目,假如模塊間耦合度大也會下降代碼的可重用性或許說復用性。所以也出現了下降耦合的觀察者形式或許宣布/定閱形式。這關於提拔代碼重用,復用性和防止單點故障等都很主要。說到這裏,還想趁便提一下近來盛行起來的相應式編程(RxJS),相應式編程中有一個很中心的觀點就是 observable,也就是 Rx 中的流(stream)。它能夠被 subscribe,實在也就是觀察者設想形式。

補充瀏覽

總結

未來前端龐雜度不停增添已成定論,跟着後端成熟,天然會將核心轉移到前端範疇,而且效勞化、用戶體驗愈來愈主要,前端體驗早不是當初能看就行,任何網頁的非常、視覺的差別,或案牘的隱約,都邑致使用戶流失,付出中綴。前端對公司營收的影響,逐漸與後端效勞宕機一致嚴峻,所以前端會愈來愈重,非常監控,機能檢測,東西鏈,可視化等等都是這幾年人人逐步注重起來的。

我們早已不能將 javascript 初期玩具性子的模塊化計劃用於當代愈來愈主要的體系中,前端界必定出現一致重量級的模塊化治理計劃,謝謝 TC39 制訂的 ES2015 模塊化範例,我們已離不開它,哪怕一切人必需運用 babel。

話說回來,規範推進的太慢,我們照樣把編譯東西看成常態,抱着哪怕支撐了 ES2015 一切特性,babel 依舊另有效的心態,將預編譯進行到底。一句話,模塊化仍在路上。js 模塊化的鋒芒已瞄準了 css 與 html,這兩位元老也該向前衛的 js 進修進修了。

未來 css、html 的模塊化會自立門戶,照樣給予 js 更強的才能,讓二者的模塊化依附於 js 的才能呢?現在 html 有自立門戶的苗頭(htmlModules),而 css 遲遲沒有轉變,社區出現的 styled-component 已用 js 將 css 模塊化得很好了,最新 css 範例也支撐了與 js 的變量通訊,豈非願望依附於 js 嗎?這裏願望獲得人人更普遍的議論。

我也認同,畢竟緊縮、殽雜、md5、或許應用 nonce 屬性對 script 標籤加密,都離不開當地構建東西。

聽說 http2 的優化中,有個最好文件大小與數目的比例,那末照樣脫離不了構建東西,前端未來會愈來愈龐雜,同時也愈來愈優美。

至此,關於 javascript 模塊化議論已靠近尾聲,對其優缺點也基礎達成了一致。前端龐雜度不停提高,促使着模塊化的革新,代辦(瀏覽器、node) 的支撐水平,與前端特殊性(流量、緩存)能夠前端永久也離不開構建東西,新的規範會讓這些事情做的更好,同時庖代、加強部份特性,前端的未來是越發優美的,龐雜度也更高。

假如你想介入議論,請點擊這裏,每周都有新的主題,每周五宣布。

    原文作者:黃子毅
    原文地址: https://segmentfault.com/a/1190000014747913
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞