Vite 是
Vite 是一個超快的前端建置工具,能夠顯著提升前端開發體驗。
- 極速的服務啟動
- 輕量快速的模組熱替換
- 豐富的功能
- 優化後的構建
總覽
- 作為開發伺服器 (dev server)
讓開發者可以在本地 (localhost) 進行開發。Vite 的熱模組更新 (hot module replacement, HMR) 提供開發者非常好的開發體驗。當有任何的改動後,Vite 的熱模塊更新會以非常快的速度重新渲染本地的頁面。 - 打包程式碼
Vite 背後是透過 Rollup 進行打包,高度優化部署到生產環境 (production) 的打包結果。
它解決了哪些問題?
1. 解決開發伺服器過慢
當我們在建立越來越大型應用的過程中,不僅需要處理的 JavaScript 程式碼量呈指數級增長,依賴的套件也會變多,慢慢成長為數千個模組的大型專案。基於 JavaScript 開發的工具就會開始遇到效能瓶頸:通常需要很長時間才能啟動開發伺服器,即使使用模組熱替換(HMR),檔案修改後的效果也需要幾秒鐘才能在瀏覽器中反映出來,更別說反應時間也會越來越長,這造成了開發體驗的問題。
啟動過慢
當啟動開發伺服器時,如果用基於打包工具 (bundler-based) 的設置,會需要先把你整個應用程式都走過一遍,然後才能啟動伺服器。Vite 則是通過把應用程式中的模組分為兩類來加快開發服務器的啟動時間,依賴 (dependencies) 及 源碼 (source code)。
依賴 (dependencies) 大多是普通的 JavaScript,開發過程中不會經常改變。一些大型的依賴(例如擁有數百個模組的元件庫)處理起來也相當耗時。依賴還可能以不同的模組格式提供(例如 ESM
或 CommonJS
)。Vite 使用 esbuild
預先打包這些依賴。esbuild
是用 Go 語言寫的,相較基於 JavaScript 的打包工具快 10 到 100 倍,這讓 Vite 加快速度不少。
源碼 則通常需要轉換 JSX
、CSS
或 Vue/Svelte
元件等非純 JavaScript 的東西,並且會經常被更動。然而,並不是所有的源碼都需要同時加載(例如,基於路由的分割的程式碼,只有在到某個路由時才需要加載)。Vite 通過原生 ESM
來提供源碼。實際上這是讓瀏覽器接管了打包工具的部分工作,Vite 只需要根據瀏覽器的請求,按需轉換和提供源碼。只有在當前某個元件被實際使用時,才會動態載入背後的程式碼,這也樣讓最開始要啟動伺服器的程式碼減少,自然讓啟動變快。
更新過慢
在基於打包工具 (bundler-based) 的設置中,當一個文件被更新後,重新構建整個包效率會很低。因為更新速度會隨著應用程式大小的增加而下降 (越大包,打包起來越慢)。
在某些打包工具中,開發服務器會將構建完的內容存在記憶體中,但是當文件改變時,它仍然需要重新構建並重載頁面。重新構建打包可能很耗時,並且重新加載頁面會消除應用程式當前的狀態 (state)。這就是為什麼一些打包工具支持熱模組替換(HMR):允許模組在不影響頁面其餘部分的情況下「熱替換」自己。這大大提高了開發體驗(DX),但實際上,即使是 HMR,隨著應用程式大小的增長,更新速度也會顯著下降。
在 Vite 中,HMR 是通過原生 ESM
進行的。當一段程式碼被更新時,Vite 只需要準確地使更新的模組與其最近的 HMR 邊界之間的鏈路失效 (大多數時候只是模組本身),這使得 HMR 更新不管應用程式的大小如何都能維持高速。
此外,Vite 還利用 HTTP 標頭來加速整頁重載 (這也是利用瀏覽器來幫忙):源碼的模組請求是通過 304 Not Modified
請求,而依賴模組則通過 Cache-Control: max-age=31536000,immutable
來快取,這樣快取便可以確保這些依賴不會再次觸及開發伺服器,更新時速度也就大幅提升。
2. 生產環境的程式碼打包
雖然現在原生的 ES Module
已經獲得廣泛的支持,但如果直接在生產環境使用沒打包的 ES Module
仍是沒效率的,由於嵌套引入 (nested import) 會需要額外的網路傳輸往返,即使開啟 HTTP/2 也是,而額外的網路傳輸就需要額外的時間。雖然在本地開發時 Vite 是透過 esbuild 預打包,但生產環境並不使用 esbuild 作為打包工具,因此為了在生產環境中,能有最佳的加載性能,Vite 透過 Rollup 協助進行打包的過程中,透過 tree-shaking、lazy-loading、common chunk splitting 等方式,可以讓打包出的結果能夠獲得優化。
功能
預打包構建
當你首次啟動 Vite 時,Vite 在本地加載你的網站之前會預先建立了專案依賴,這使用 esbuild 將 CommonJS / UMD
轉換為 ESM
格式,並重寫導入為合法的 URL,例如 /node_modules/.vite/deps/my-dep.js?v=f3sf2ebd
以便讓瀏覽器能夠正確匯入它們。
熱模組更新
Vite 提供了一套原生 ESM 的 HMR API。 具有 HMR 功能的框架可以利用該 API 提供即時、準確的更新,而無需重新載入頁面或清除應用程式狀態。
TS 支持
Vite 本身支持 .ts
檔,但 Vite 僅執行 .ts
檔案的轉譯工作,並不執行任何類型檢查。這是由於 Vite 假定類型檢查已經被你的 IDE 或建置過程處理了,而且類型檢查需要了解整個模組圖,若把型別檢查塞進 Vite 的轉換管道,將不可避免地損害 Vite 的速度優勢,因為 Vite 的工作是盡可能快速地將來源模組轉化為可以在瀏覽器中運行的形式。