Vite 概念整理與快速建置

在這篇文章中,我詳細介紹了 Vite 這個前端開發工具,它利用原生 ES Module 的方式改進了傳統 webpack 的打包方式,大幅提升了開發環境的打包速度。我解釋了 Vite 的工作原理、如何通過減少模塊請求次數和快速模塊熱更新來實現高效的開發體驗,並比較了它與 webpack 在打包技術上的主要差異。

Vite 概念整理與快速建置
Photo by Adi Goldstein / Unsplash
Vite 是 Vue.js 的作者所做的一個新的 bundler,這個工具可以提升開發環境的打包速度

一、Vite 是什麼? Vite 的原理是甚麼?

Vite 是法文的「快」,念法「veet」,與原本的打包工具相比速度快了 10-20 倍。

由於 ES6 後多數瀏覽器可以用 native ESM 使用 import 和 export,Vite 的 dev server 藉著改用原生 ES module 的方式而非過去 webpack 走訪整個專案中的模塊一一打包成 require ,也因此提供了較快速順暢的開發體驗。

圖片來源: Rookie’s Notes — Vite and Devtools in Vue 3


二、為什麼 Vite 可以節省時間?

1. 真正的按需加載

利用瀏覽器對 ES Module 的支持,實現真正的按需加載

2. 快速的冷啟動

No Bundle + ESBuild 預構建
  • CommonJS 和 UMD 兼容性
    • 由於 Vite 是基於瀏覽器原生支持 ES Module 的能力去實現的
    • 但是在開發階段中,Vite 將所有代碼視為原生 ES Module 模塊
    • 因此 Vite 必須提前將 CommonJS 和 UMD 發布的依賴項轉換為 ES Module
    • 並緩存入 node_modules/.vite
  • 減少模塊和請求的數量
    • Vite 將有許多內部模塊的 ESM 依賴關係轉換為單個模塊,以此來提高頁面的加載性能
    • 一些包將他們的 ES Module 構建作為許多獨立的文件相互導入,比如 lodash-es 有超過 600 個內置模塊,當解析 import { debounce } from ‘lodash-es’ 時,瀏覽器同時發出 600 多個 HTTP 請求!這些請求會造成網絡擁堵,影響頁面的加載。因此 Vite 通過預構建將 lodash-es 構建為一個模塊,所以只需要一個 HTTP 請求即可

3. 即時的模塊熱更新

基於 ES Module 的 HMR,同時利用瀏覽器緩存策略提升速度

熱更新簡單來說就是在 Server 與瀏覽器建立了一個 websocket 連線,當程式碼被修改時,Server 會傳送訊息通知瀏覽器去請求修改模組的程式碼,能在不刷新瀏覽器的前提下進行更新。

在 HMR(熱更新)方面,vite 透過 webSocket/Chokidar/esbuild 即時編譯修改的程式碼,並透過暫存機制加載來更新後的內容。當改動了一個模塊後,vite 僅需讓瀏覽器重新請求該模塊即可,不像 webpack 那樣需要把該模塊的相關依賴模塊全部編譯一次,效率更高。


三、Vite 與 Webpack 差別在哪?

之前多數瀏覽器只支持 CommonJS 所以要打包轉換,webpack 主要是通過「抓取 -> 編譯 ->構建」整個應用的代碼,之後生成一份編譯,優化後能良好地兼容各個瀏覽器的代碼。

由於 ES6 後多數瀏覽器可以用 native ESM 使用 import 和 export,Vite 就是基於瀏覽器原生支持 ES Module ,根據 Http 的 request 來載入模組進行處理,實現真正的依需求加載,提升開發速度。

webpack 或者類似的工具叫做「bundler」就是要把你的 JS 檔案跟 dependencies 打包在一起

儘管你在寫程式的時候是用 import 跟 export,但是在輸出時很有可能已經被 babel 或者是 webpack 轉成 CommonJS 或是其他形式外面還有再包一層支持瀏覽器來解析 require 這一些語法。

而這也是 webpack 這些打包工具之所以慢的原因,那就是他們需要靜態分析過 app 的所有檔案以及套件的相依性,然後根據這些資訊把東西包在一起,當你的檔案愈來愈大的時候,花的時間也就自然愈來愈多,因為 webpack 要搞清楚到底要怎麼打包。

不過 vite 在 production build 時還是會做打包

vite 打包時不是用 webapck 是用 rollup 這個工具,之所以在正式環境還是需要像 wepack 一樣打包是因為瀏覽器就必須要發出一個個的 request 來取得各個 js 檔,這樣才知道下一個相依性在哪,才能再取得下一個。

而在正式環境這樣的加載需要的時間較長,所以要在一開始走訪所有的檔案來取得相依性,這雖使得啟動的時間會加長但能解決套件相依性拉長加載時間的問題。


四、Vite 使用上需要注意的事


五、Vite 快速安裝

npm init vite@latest
再來請輸入 **專案名稱** 及 **選擇你想使用的框架**。
cd 你的專案名稱
npm install
npm run dev

※ Window 環境可能遇到此問題failed with code 1


六、Vite 專案架構

├── README.md
├── index.html //放置於根目錄
├── node_modules
├── package.json
├── public
├── src
│   ├── App.vue
│   ├── assets
│   ├── components
│   └── main.js 
├── vite.config.js
└── yarn.lock

七、延伸討論的問題

  1. 為什麽 require 不好用?
    • 沒有 Module 這樣的設計模式,來讓你的變數不會衝突
    • 加入其他的 Dependency(相依函示庫),還是只能用Embedded JavaScript慢慢加
  2. 上線時 vite 是否是用 require 的方式?
    • 不是,Rollup 是一個針對 ES6 Module 所設計的打包工具,使用 ES6 Module
參考資料webpack与 vite 的区别Vite原理浅析 - 知乎专栏