691 字
3 分鐘

Vite 拆包怎麼設:先看產物與載入路徑,再決定要不要 manualChunks

看到初始 JavaScript 變大時,很多人會立刻在 Vite 加一個 manualChunks(),把所有 node_modules 收進 vendor。這不是預設安全的效能修正:拆包會改變模組的載入時機與快取邊界,過度手動分組也可能把本來不需一開始下載的程式碼提前載入。

直接答案是:先量測目前產物與進入點,再只為可辨識的重型、低頻或共用模組建立 chunk;每次升級 Vite 的底層 bundler 時,重新確認設定名稱與行為。

先保留預設,找出真正的大檔#

先執行正式建置並看輸出大小:

Terminal window
pnpm vite build

Vite 的 production build 會產生適合靜態託管的 bundle。若路由或動態 import 已把低頻功能分開,新增 manualChunks 不一定有益;先找出哪個 entry、依賴或共同模組讓初始路徑變大,再決定是否介入。

manualChunks 適合什麼問題#

Rollup 的函式形式會把符合的 module 與其相依項目加入指定 chunk。簡單範例如下:

// 先用在確認過的重型且低頻功能,不是所有套件
manualChunks(id) {
if (id.includes('/node_modules/monaco-editor/')) {
return 'editor';
}
}

這能讓只有進入編輯器的使用者才下載 editor chunk;但不要用 package 名稱的模糊比對,也不要假設所有第三方套件都該集中成 vendor。檢查實際 resolved id,避免 foo 意外命中 foo-utils

三個容易漏掉的風險#

  1. 函式形式預設會一併合併相依項目,可能讓 chunk 比預期大。
  2. 手動 chunk 可能讓有 side effect 的模組比原本更早執行,進而改變應用程式行為。
  3. Rollup 文件指出 onlyExplicitManualChunks 的預設會在 Rollup 5 改變;Vite 升級或切換底層 bundler 時,不能只複製舊設定。

因此每次調整後都應測兩件事:首次進入主要頁面的 network waterfall,以及進入延遲功能時是否仍會正確載入。若有 deploy 後舊頁面載不到動態 chunk,可監聽 Vite 的 vite:preloadError,並確認 HTML 的快取策略不會長期引用已刪除的舊檔名。

一個可重複的拆包流程#

先以預設設定建置,再用 bundle 視覺化或瀏覽器 network 資料找出具體問題;只為一個明確的載入路徑新增規則;重新建置並測試入口與延遲頁;最後把「為何拆、如何驗證」記錄在設定旁。這比維護一串例外套件名更容易在下次依賴升級時判斷是否仍需要。

若你正在處理 Vite 的設定資料,也請把公開環境變數和 secret 分開;可參考 Vite .env 的前端密鑰邊界

參考資料:

Vite Docs:Building for Production

Rollup Docs:output.manualChunks

Vite 拆包怎麼設:先看產物與載入路徑,再決定要不要 manualChunks
https://laplusda.com/posts/optimize-vite-build-with-custom-chunking/
作者
Zero
發佈於
2024-08-27
許可協議
CC BY-NC-SA 4.0
這篇文章有幫助嗎?

回報錯字、失效連結,或告訴我你想看的延伸主題。