<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Bundleless,前端工程構(gòu)建的未來

          共 4116字,需瀏覽 9分鐘

           ·

          2021-06-09 11:58

          Bundle or Bundleless?自 2015 年 ESM 標準發(fā)布后,路線之爭就開始逐步升溫。轉(zhuǎn)眼間,時間已來到 2021 年。如果白酒的車你錯過了,那么不妨看看 Bundleless,或許它就是前端圈的下一位「茅臺」。

          前端構(gòu)建當下的問題

          不得不說,曾經(jīng)把自己定位為「打包器」的 Webpack,如今已形成強大的構(gòu)建生態(tài),儼然一統(tǒng)江湖。但前端構(gòu)建的道路還遠沒有走到最后。隨著業(yè)務(wù)的發(fā)展,前端工程的復(fù)雜度越來越高,構(gòu)建方面的也開始暴露出新的問題。

          構(gòu)建時間逐步拉長

          相信許多前端同學剛?cè)胄袝r,都經(jīng)歷過「刷新一下全都有」的幸福時光:寫幾個 HTML 標簽,寫幾句內(nèi)嵌代碼,瀏覽器中就會呈現(xiàn)出美妙的 UI。而如今,業(yè)務(wù)工程越來越復(fù)雜,代碼量連年增長,構(gòu)建的時間也越來越長。曾經(jīng)「秒級構(gòu)建」的前端,終究躋身「分鐘級構(gòu)建」的圈子了。

          前端工程構(gòu)建時間的拉長,自然使得前端開發(fā)者在日常業(yè)務(wù)工作中的狀態(tài),從圖左逐漸運動到了圖右。

          模塊標準引領(lǐng)方向

          如果我們縱觀前端領(lǐng)域的發(fā)展,就可以看到標準是如何推動各大瀏覽器建設(shè),整個前端生態(tài)又是如何發(fā)生的變化。

          2002 年,AJAX 推出,此后前端承擔的工作越來越多。彼時,瀏覽器廠各行其是,因此兼容性是當時的主要問題。于是 2006 年,jQuery 的出現(xiàn)進一步帶動了前端的發(fā)展。

          2009 - 2011 年,CommonJS、AMD、UMD 相繼為 JS 帶來了模塊規(guī)范。同一時期,部分遵循 CommonJS 的 Node 為 JS 帶來了運行環(huán)境,為前端工程化的解鎖奠定基礎(chǔ):

          • 模塊加載工具開始涌現(xiàn),如 RequireJS、SeaJS 等
          • 包管理工具,如 npm、spm 等
          • 輕量的打包器開始出現(xiàn),如 Browserify
          • 任務(wù)工具開始出現(xiàn),如 Gulp

          Angular、React、Vue 等的相繼火爆,也推動了前端的又一波浪潮:它們的發(fā)展提高了前端在業(yè)務(wù)中的表達能力,并向更高程度的工程化提出訴求。

          2015 年,HTTP/2.0 推出,同時 JS 迎來了自己的模塊標準 ESM:ES2015 一發(fā)布,Babel 就讓開發(fā)者們用上了 ES Module,真香。于是此后的幾年,Webpack & Babel 幾乎成了前端工程化的代名詞,甚至讓人以為,前端工程化已成定局。

          2018 年,Chrome、Safari、Firefox 相繼完成了對 ESM 的支持。但得益于 Webpack 生態(tài)對 CommonJS、AMD、UMD 的支持,開發(fā)者們對 ESM 的享用更多是在編碼階段和一定程度的 Tree-shaking,在構(gòu)建層面并沒有直接的得利。

          小結(jié)

          當下時間點,出現(xiàn)了新的契機:其一,「工程體積的日益增長」與「亟待提升的構(gòu)建性能」之間的矛盾;其二,「先進的前端模塊標準」與「落后的前端模塊規(guī)范」之間的矛盾。

          Bundleless 為什么是答案

          Bundleless 說到底,就是指無打包構(gòu)建,與我們當下流行的打包構(gòu)建相對,而打包器則是我們前端開發(fā)者用于將 JS 模塊打包成單一的、可在瀏覽器內(nèi)運行的文件的工具。

          為什么過去需要打包

          這一問題在社區(qū)也有非常多的總結(jié),概況來講,主要包括以下理由:

          • HTTP/1.1 各瀏覽器有并行連接限制
          • 瀏覽器不支持模塊系統(tǒng)(如 CommonJS 包不能直接在瀏覽器運行)
          • 代碼依賴關(guān)系與順序管理

          HTTP/1.1 各瀏覽器默認并行連接數(shù)

          瀏覽器Firefox 3+Opera 12Safari 5IE 7IE 10EdgeChrome
          并行連接6662866

          為什么開始嘗試不打包

          近幾年時間,標準的確立、瀏覽器大廠和前端生態(tài)的跟進,使得「不打包」成為可能:

          • HTTP/2.0 多路并用
          • 各大瀏覽器逐一支持 ESM
          • 越來越多的 npm 包擁抱 ESM(盡管很多包的依賴并不是)

          我們可以發(fā)現(xiàn):

          • 通過打包來減少網(wǎng)絡(luò)請求數(shù)量從而提高性能的優(yōu)化手段理論上在 HTTP/2.0 下會變得不再必要;
          • ESM 標準的推廣和各大瀏覽器的支持:
          • 讓模塊代碼可以直接在瀏覽器中運行
          • 原生的解決了代碼依賴和復(fù)用的問題
          • 會進一步推動越來越多的npm 包支持 ESM,甚至會出現(xiàn)新的包管理或分發(fā)方式

          模塊加載的對比

          如果是打包式構(gòu)建,在模塊加載時,實際上加載的是若干模塊的集合。這種方式的優(yōu)點是以少量的請求連接數(shù)完成 JS 腳本的下載。如果是無打包式構(gòu)建,模塊的加載則是基于原生模塊方案,直接獲取具體的模塊腳本。

          本地開發(fā)構(gòu)建的對比

          如果是打包式構(gòu)建,無論是項目啟動還是文件變更,都需要完整的走一遍打包過程。以 Webpack 為例,我們就會經(jīng)歷依賴分析、代碼轉(zhuǎn)譯和打包的過程,哪怕我們只是簡單的修改了一行文案。當然,Split chunk 會在一定程度上緩解這一問題,但粒度仍然偏大。

          而無打包式構(gòu)建,在啟動過程中基本只是啟動服務(wù)(當然不同的 Bundleless 方案可能還會做些其他的工作),而不用對業(yè)務(wù)代碼進行依賴分析、打包,ESM 會幫助我們在瀏覽器中完成依賴的分析。當文件發(fā)生變更時,本地開發(fā)服務(wù)只是提供了文件的映射,只需要重新轉(zhuǎn)譯對應(yīng)的文件,并重新替換即可。

          以上,我們可以知道:

          • 打包過程的必要性已降低
          • 擁抱 ESM 是未來趨勢

          社區(qū)在領(lǐng)域內(nèi)的工作

          前端構(gòu)建并不只是構(gòu)建工具的問題。事實上,「構(gòu)建」和「分發(fā)」共同組成了前端工程的構(gòu)建,只不過通常情況下,我們是通過 npm install 將三方包下載下來,并打包到構(gòu)建結(jié)果中實現(xiàn)的。

          構(gòu)建可以分為兩種類型。

          一種是基于服務(wù)的構(gòu)建方式,通常服務(wù)于實際生產(chǎn)。我們可以再細分成本地服務(wù)構(gòu)建遠端服務(wù)構(gòu)建本地服務(wù)構(gòu)建就是我們常規(guī)的操作,目前基本已經(jīng)被 Webpack 統(tǒng)治,是 Bundle 方案的代表;Snowpack、Vite、Web Dev Server 則是目前非常火的 Bundleless 方案,近一年的時間里勢頭迅猛。遠端服務(wù)構(gòu)建則是依托云能力的玩法,把構(gòu)建過程放在服務(wù)端完成,從而把本地的開發(fā)流程搬到 Web 上,并給出于本地服務(wù)構(gòu)建基本一致的體驗。

          另一種是基于瀏覽器的構(gòu)建方式,通常面向 Demo 的快速搭建或預(yù)覽方案。Codesandbox、StackBlitz、CodePen 和 Riddle 是業(yè)內(nèi)較出色的方案,整體是在瀏覽器端實現(xiàn)代碼的編譯、打包、構(gòu)建和運行。當然,具體到各個方案的細節(jié),通常對服務(wù)還是有一定依賴。

          目前來看,100% 在瀏覽器端進行打包、構(gòu)建,現(xiàn)階段并不是最理想的方案。隨著 Bundleless 的發(fā)展,瀏覽器 Bundleless 和包分發(fā)平臺的結(jié)合會得到進一步的發(fā)展,并逐步影響前端工程的架構(gòu)。

          這一部分在 Snowpack 的文檔上有一定的講解。整體來說,Snowpack 盡可能利用了現(xiàn)有前端生態(tài)的工具,對三方包打包來壓縮依賴鏈,對業(yè)務(wù)代碼走無構(gòu)建路線,以此提供 Bundleless 體系下的開發(fā)體驗。值得一提的是,Snowpack 的構(gòu)建速度很快,這得益于內(nèi)置打包工具 esbuild 的發(fā)展。

          我們不妨將其與 Webpack 進行一個對比。

          啟動時間,如上文所說,Webpack 會完整打包整個項目,因此隨著項目體積的增長,啟動時間也會越發(fā)漫長;而 Snowpack 主要是啟動本地的服務(wù),對于 Snowpack 來說,盡管初次啟動時會分析三方依賴,并通過 Rollup 將其進行打包,但是打包結(jié)果會緩存在 node_modules/.cache/snowpack/development 目錄下,后續(xù)就可以享受到飛一樣的啟動。

          構(gòu)建時間,對于 Webpack 而言,構(gòu)建時長會隨著項目體積整體以線性方式增長;而 Snowpack 的模式則是 O(1) 的復(fù)雜度(當然這里也有點小噱頭)。

          緩存能力,可以說 Webpack 的緩存利用率尚有優(yōu)化空間。盡管我們可以通過 Split Chunk,合理的劃分打包方式,但如果我們只是改了一句文案,那么用戶側(cè)仍然會重新獲取對應(yīng) Chunk 資源。Snowpack 的緩存利用率近乎完美。業(yè)務(wù)代碼文件發(fā)生變更,直接替代產(chǎn)出資源,其他全部可返回緩存;三方依賴包,如 react.js,則直接更新該包,其他全部可用緩存。不過,盡管生產(chǎn)環(huán)境優(yōu)化可以做 Tree-shaking,但是業(yè)務(wù)代碼本身,Snowpack 并不會做處理(只是以 ESM 來對待),即使使用 Snowpack 生態(tài)的 Webpack 插件來做生產(chǎn)環(huán)境的構(gòu)建也是如此,所以是近乎完美,這是相對于理想的 DCE(dead code elimination) 而言的。Webpack 在生產(chǎn)環(huán)境會把沒有使用到的代碼 Tree-shaking 掉,不可謂不強大。

          至于調(diào)試體驗,因為 Webpack 需要打包,因此在調(diào)試的時候我們依賴 SourceMap 來幫助我們看到源碼。但對于 Snowpack 而言(實際上 Bundleless 模式都是如此),我們并不強依賴于 SourceMap,如果轉(zhuǎn)譯后的代碼閱讀無礙(ES6 其實還好嘛),就可以直接進行單文件調(diào)試。

          不過即使 Snowpack 有千番好,整個 Bundleless 生態(tài)還不足以取代 Webpack。Webpack 終究是一代神器,只是我們明白 Bundleless 也確實代表了未來。

          ??Vite

          Vite 是尤大的力作,本篇便不再對其進行討論。有趣的是,他和 Webpack 作者 Sean 在推上的討論可以看出,大佬們也在 Bundleless 方向不斷發(fā)力,Webpack 成為了大家發(fā)起挑戰(zhàn)的目標。

          本文以 Bundleless 為切入點,結(jié)合前端構(gòu)建的發(fā)展過程,對當下無構(gòu)建方案進行了討論。未來我們會更多的在此方面進行實踐。

             原文鏈接:https://zhuanlan.zhihu.com/p/349406330

          瀏覽 62
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天天色天天干天天色 | 久久手机看片 | 波多野结衣一二三区乱码 | 国产黄色成人影片 | 天天干天天爽天天玩 |