依賴預構建
當你首次執行 vite 時,Vite 會在本地載入站點之前預構建專案依賴。此過程預設自動且透明地完成。
為什麼需要預構建
這就是 Vite 所稱的“依賴預構建”。該過程主要有兩個目的:
CommonJS 和 UMD 相容性: 在開發過程中,Vite 將所有程式碼作為原生 ESM 提供。因此,Vite 必須先將以 CommonJS 或 UMD 格式釋出的依賴項轉換為 ESM。
在轉換 CommonJS 依賴時,Vite 會執行智慧匯入分析,確保對 CommonJS 模組的具名匯入能按預期工作,即使匯出是動態分配的(例如 React)。
js// works as expected import React, { useState } from 'react'效能: Vite 將包含大量內部模組的 ESM 依賴轉換為單個模組,以提高後續頁面的載入效能。
一些包將它們的 ES 模組構建為許多相互匯入的獨立檔案。例如,
lodash-es有超過 600 個內部模組!當我們執行import { debounce } from 'lodash-es'時,瀏覽器會同時發出 600 多個 HTTP 請求!雖然伺服器處理這些請求沒有問題,但大量的請求會在瀏覽器端造成網路擁塞,導致頁面載入明顯變慢。透過將
lodash-es預構建為單個模組,我們現在只需要一個 HTTP 請求!
注意
依賴預構建僅適用於開發模式。
自動依賴發現
如果未找到現有快取,Vite 會抓取你的原始碼並自動發現依賴項匯入(即預期從 node_modules 解析的“裸匯入”),並將這些發現的匯入作為預構建的入口點。預構建過程由 Rolldown 執行,因此通常非常快。
伺服器啟動後,如果遇到了快取中不存在的新依賴匯入,Vite 將重新執行依賴構建過程,並在必要時重新載入頁面。
Monorepos 和連結依賴
在 Monorepo 設定中,依賴項可能是來自同一倉庫的連結包。Vite 會自動檢測未從 node_modules 解析的依賴項,並將其視為原始碼。它不會嘗試構建該連結依賴,而是會分析該連結依賴的依賴列表。
但是,這要求連結的依賴項必須匯出為 ESM。如果不是,你可以將其新增到配置檔案的 optimizeDeps.include 中。
export default defineConfig({
optimizeDeps: {
include: ['linked-dep'],
},
})對連結的依賴項進行更改時,請使用 --force 命令列選項重啟開發伺服器以使更改生效。
自定義行為
預設的依賴發現啟發式演算法並不總是理想的。如果你想顯式地包含或排除某些依賴項,請使用 optimizeDeps 配置選項。
optimizeDeps.include 或 optimizeDeps.exclude 的典型用例是當你有一個在原始碼中無法直接發現的匯入時。例如,該匯入可能是外掛轉換的結果。這意味著 Vite 無法在初始掃描時發現它——只能在瀏覽器請求並轉換該檔案後才能發現。這將導致伺服器在啟動後立即重新構建。
include 和 exclude 都可以用來處理這種情況。如果依賴項很大(包含許多內部模組)或者是 CommonJS,則應該將其包含進來;如果依賴項很小且已經是有效的 ESM,你可以將其排除,讓瀏覽器直接載入它。
你還可以透過 optimizeDeps.rolldownOptions 選項進一步自定義 Rolldown。例如,新增一個 Rolldown 外掛來處理依賴項中的特殊檔案,或更改 構建 target。
快取
檔案系統快取
Vite 將預構建的依賴項快取在 node_modules/.vite 中。它基於以下幾個來源確定是否需要重新執行預構建步驟:
- 包管理器的鎖檔案內容,例如
package-lock.json、yarn.lock、pnpm-lock.yaml或bun.lock。 - 補丁資料夾的修改時間。
vite.config.js中的相關欄位(如果存在)。NODE_ENV的值。
預構建步驟僅在上述任一項發生更改時才會重新執行。
如果由於某種原因你想要強制 Vite 重新構建依賴項,可以啟動開發伺服器時帶上 --force 命令列選項,或者手動刪除 node_modules/.vite 快取目錄。
瀏覽器快取
解析後的依賴請求會透過 HTTP 頭 max-age=31536000,immutable 進行強快取,以提高開發時的頁面過載效能。一旦快取,這些請求將永遠不會再次觸及開發伺服器。如果安裝了不同版本(反映在包管理器的鎖檔案中),它們會自動透過附加的版本查詢引數失效。如果你想透過本地編輯來除錯依賴項,你可以:
- 透過瀏覽器開發者工具的網路選項卡臨時停用快取。
- 使用
--force標誌重啟 Vite 開發伺服器以重新構建依賴項。 - 重新載入頁面。
