當(dāng)你首次啟動 vite
時,你可能會注意到打印出了以下信息:
Optimizable dependencies detected: (偵測到可優(yōu)化的依賴:)
react, react-dom
Pre-bundling them to speed up dev server page load...(將預(yù)構(gòu)建它們以提升開發(fā)服務(wù)器頁面加載速度)
(this will be run only when your dependencies have changed)(這將只會在你的依賴發(fā)生變化時執(zhí)行)
這就是 Vite 執(zhí)行的所謂的“依賴預(yù)構(gòu)建”。這個過程有兩個目的:
1、CommonJS 和 UMD 兼容性: 開發(fā)階段中,Vite 的開發(fā)服務(wù)器將所有代碼視為原生 ES 模塊。因此,Vite 必須先將作為 CommonJS 或 UMD 發(fā)布的依賴項轉(zhuǎn)換為 ESM。
當(dāng)轉(zhuǎn)換 CommonJS 依賴時,Vite 會執(zhí)行智能導(dǎo)入分析,這樣即使導(dǎo)出是動態(tài)分配的(如 React),按名導(dǎo)入也會符合預(yù)期效果:
// 符合預(yù)期
import React, { useState } from 'react'
2、性能: Vite 將有許多內(nèi)部模塊的 ESM 依賴關(guān)系轉(zhuǎn)換為單個模塊,以提高后續(xù)頁面加載性能。
一些包將它們的 ES 模塊構(gòu)建作為許多單獨的文件相互導(dǎo)入。例如,??lodash-es
?? 有超過 600 個內(nèi)置模塊!當(dāng)我們執(zhí)行 ?import { debounce } from 'lodash-es'
? 時,瀏覽器同時發(fā)出 600 多個 HTTP 請求!盡管服務(wù)器在處理這些請求時沒有問題,但大量的請求會在瀏覽器端造成網(wǎng)絡(luò)擁塞,導(dǎo)致頁面的加載速度相當(dāng)慢。
通過預(yù)構(gòu)建 ?lodash-es
? 成為一個模塊,我們就只需要一個 HTTP 請求了!
如果沒有找到相應(yīng)的緩存,Vite 將抓取你的源碼,并自動尋找引入的依賴項(即 "bare import",表示期望從node_modules
解析),并將這些依賴項作為預(yù)構(gòu)建包的入口點。預(yù)構(gòu)建通過 ?esbuild
?執(zhí)行,所以它通常非???。
在服務(wù)器已經(jīng)啟動之后,如果遇到一個新的依賴關(guān)系導(dǎo)入,而這個依賴關(guān)系還沒有在緩存中,Vite 將重新運行依賴構(gòu)建進程并重新加載頁面。
在一個 monorepo 啟動中,該倉庫中的某個依賴可能會成為另一個包的依賴。Vite 會自動偵測沒有從 node_modules
解析的依賴項,并將鏈接的依賴視為源碼。它不會嘗試打包被鏈接的依賴,而是會分析被鏈接依賴的依賴列表。
Note
由于依賴關(guān)系的處理方式不同,鏈接的依賴關(guān)系在最終構(gòu)建時可能無法正常工作。 使用 ?npm package
? 代替所有本地依賴,以避免最終的 bundle 問題。
默認(rèn)的依賴項發(fā)現(xiàn)為啟發(fā)式可能并不總是可取的。在你想要顯式地從列表中包含/排除依賴項的情況下, 請使用 ?optimizeDeps
? 配置項。
當(dāng)你遇到不能直接在源碼中發(fā)現(xiàn)的 import 時,?optimizeDeps.include
? 或 ?optimizeDeps.exclude
? 就是典型的用例。例如,import 可能是插件轉(zhuǎn)換的結(jié)果。這意味著 Vite 無法在初始掃描時發(fā)現(xiàn) import —— 它只能在瀏覽器請求文件時轉(zhuǎn)換后才能發(fā)現(xiàn)。這將導(dǎo)致服務(wù)器在啟動后立即重新打包。
?include
?和 ?exclude
?都可以用來處理這個問題。如果依賴項很大(包含很多內(nèi)部模塊)或者是 CommonJS,那么你應(yīng)該包含它;如果依賴項很小,并且已經(jīng)是有效的 ESM,則可以排除它,讓瀏覽器直接加載它。
Vite 會將預(yù)構(gòu)建的依賴緩存到 ?node_modules/.vite
?。它根據(jù)幾個源來決定是否需要重新運行預(yù)構(gòu)建步驟:
package.json
? 中的 ?dependencies
?列表package-lock.json
?, ?yarn.lock
?,或者 ?pnpm-lock.yaml
?vite.config.js
? 相關(guān)字段中配置過的只有在上述其中一項發(fā)生更改時,才需要重新運行預(yù)構(gòu)建。
如果出于某些原因,你想要強制 Vite 重新構(gòu)建依賴,你可以用 ?--force
? 命令行選項啟動開發(fā)服務(wù)器,或者手動刪除 ?node_modules/.vite
? 目錄。
解析后的依賴請求會以 HTTP 頭 ?max-age=31536000,immutable
? 強緩存,以提高在開發(fā)時的頁面重載性能。一旦被緩存,這些請求將永遠(yuǎn)不會再到達(dá)開發(fā)服務(wù)器。如果安裝了不同的版本(這反映在包管理器的 lockfile 中),則附加的版本 query 會自動使它們失效。如果你想通過本地編輯來調(diào)試依賴項,你可以:
--force
? 命令以重新構(gòu)建依賴;
更多建議: