Vite 為什么選擇它

2022-03-29 16:06 更新

現(xiàn)實問題

在瀏覽器支持ES模塊之前,JavaScript并沒有提供的原生機制讓開發(fā)者以模塊化的方式進行開發(fā)。這也正是我們對“打包”這個概念熟悉的原因:使用工具抓取、處理并將我們的源碼模塊串聯(lián)成可以在瀏覽器中運行的文件。

時過境遷,我們見證了諸如 webpack、Rollup 和 Parcel 等工具的變遷,它們極大地改善了前端開發(fā)者的開發(fā)體驗。

然而,當我們開始構(gòu)建越來越大型的應(yīng)用時,需要處理的 JavaScript 代碼量也呈指數(shù)級增長。包含數(shù)千個模塊的大型項目相當普遍。我們開始遇到性能瓶頸 —— 使用 JavaScript 開發(fā)的工具通常需要很長時間(甚至是幾分鐘?。┎拍軉娱_發(fā)服務(wù)器,即使使用 HMR,文件修改后的效果也需要幾秒鐘才能在瀏覽器中反映出來。如此循環(huán)往復(fù),遲鈍的反饋會極大地影響開發(fā)者的開發(fā)效率和幸福感。

Vite 旨在利用生態(tài)系統(tǒng)中的新進展解決上述問題:瀏覽器開始原生支持 ES 模塊,且越來越多 JavaScript 工具使用編譯型語言編寫。

緩慢的服務(wù)器啟動

當冷啟動開發(fā)服務(wù)器時,基于打包器的方式啟動必須優(yōu)先抓取并構(gòu)建你的整個應(yīng)用,然后才能提供服務(wù)。

Vite通過在一開始將應(yīng)用中的模塊區(qū)分為依賴和源碼兩類,改進了開發(fā)服務(wù)器啟動時間。

  • 依賴大多為在開發(fā)時不會變動的純 JavaScript。一些較大的依賴(例如有上百個模塊的組件庫)處理的代價也很高。依賴也通常會存在多種模塊化格式(例如 ESM 或者 CommonJS)。Vite 將會使用 esbuild 預(yù)構(gòu)建依賴。Esbuild 使用 Go 編寫,并且比以 JavaScript 編寫的打包器預(yù)構(gòu)建依賴快 10-100 倍。
  • 源碼通常包含一些并非直接是 JavaScript 的文件,需要轉(zhuǎn)換(例如 JSX,CSS 或者 Vue/Svelte 組件),時常會被編輯。同時,并不是所有的源碼都需要同時被加載(例如基于路由拆分的代碼模塊)。Vite 以 原生 ESM 方式提供源碼。這實際上是讓瀏覽器接管了打包程序的部分工作:Vite 只需要在瀏覽器請求源碼時進行轉(zhuǎn)換并按需提供源碼。根據(jù)情景動態(tài)導(dǎo)入代碼,即只在當前屏幕上實際使用時才會被處理。

bundler

esm

緩慢的更新

基于打包器啟動時,重建整個包的效率很低。原因顯而易見:因為這樣更新速度會隨著應(yīng)用體積增長而直線下降。
一些打包器的開發(fā)服務(wù)器將構(gòu)建內(nèi)容存入內(nèi)存,這樣它們只需要在文件更改時使模塊圖的一部分失活,但它也仍需要整個重新構(gòu)建并重載頁面。這樣代價很高,并且重新加載頁面會消除應(yīng)用的當前狀態(tài),所以打包器支持了動態(tài)模塊熱重載(HMR):允許一個模塊 “熱替換” 它自己,而不會影響頁面其余部分。這大大改進了開發(fā)體驗 —— 然而,在實踐中我們發(fā)現(xiàn),即使采用了 HMR 模式,其熱更新速度也會隨著應(yīng)用規(guī)模的增長而顯著下降。
在 Vite 中,HMR 是在原生 ESM 上執(zhí)行的。當編輯一個文件時,Vite 只需要精確地使已編輯的模塊與其最近的 HMR 邊界之間的鏈失活(大多數(shù)時候只是模塊本身),使得無論應(yīng)用大小如何,HMR 始終能保持快速更新。

Vite 同時利用 HTTP 頭來加速整個頁面的重新加載(再次讓瀏覽器為我們做更多事情):源碼模塊的請求會根據(jù) ?304 Not Modified? 進行協(xié)商緩存,而依賴模塊請求則會通過 ?Cache-Control: max-age=31536000,immutable? 進行強緩存,因此一旦被緩存它們將不需要再次請求。
一旦你體驗到 Vite 的神速,你是否愿意再忍受像曾經(jīng)那樣使用打包器開發(fā)就要打上一個大大的問號了。

為什么生產(chǎn)環(huán)境仍需打包

盡管原生 ESM 現(xiàn)在得到了廣泛支持,但由于嵌套導(dǎo)入會導(dǎo)致額外的網(wǎng)絡(luò)往返,在生產(chǎn)環(huán)境中發(fā)布未打包的 ESM 仍然效率低下(即使使用 HTTP/2)。為了在生產(chǎn)環(huán)境中獲得最佳的加載性能,最好還是將代碼進行 tree-shaking、懶加載和 chunk 分割(以獲得更好的緩存)。

要確保開發(fā)服務(wù)器和生產(chǎn)環(huán)境構(gòu)建之間的最優(yōu)輸出和行為一致并不容易。所以 Vite 附帶了一套構(gòu)建優(yōu)化的構(gòu)建命令,開箱即用。

為何不用ESBuild打包

雖然?esbuild ?快得驚人,并且已經(jīng)是一個在構(gòu)建庫方面比較出色的工具,但一些針對構(gòu)建 應(yīng)用 的重要功能仍然還在持續(xù)開發(fā)中 —— 特別是代碼分割和 CSS 處理方面。就目前來說,Rollup 在應(yīng)用打包方面更加成熟和靈活。盡管如此,當未來這些功能穩(wěn)定后,我們也不排除使用?esbuild?作為生產(chǎn)構(gòu)建器的可能。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號