Vite2.0 依賴關(guān)系預(yù)捆綁
當(dāng)你第一次運(yùn)行vite,你可能會(huì)注意到這個(gè)消息:
Optimizable dependencies detected:
react, react-dom
Pre-bundling them to speed up dev server page load...
(this will be run only when your dependencies have changed)
為什么
這就是Vite執(zhí)行的所謂的“依賴預(yù)綁定”。這個(gè)過程有兩個(gè)目的:
CommonJS和UMD兼容性:在開發(fā)過程中,Vite的dev將所有代碼作為本地ESM服務(wù)。因此,Vite必須首先將作為CommonJS或UMD發(fā)布的依賴項(xiàng)轉(zhuǎn)換為ESM。
在轉(zhuǎn)換CommonJS依賴時(shí),Vite會(huì)執(zhí)行智能導(dǎo)入分析,這樣即使導(dǎo)出被動(dòng)態(tài)分配(例如React),命名的導(dǎo)入也會(huì)像預(yù)期的那樣工作:
// works as expected
import React, { useState } from 'react'
性能:Vite將ESM與許多內(nèi)部模塊的依賴關(guān)系轉(zhuǎn)換為單個(gè)模塊,以提高后續(xù)頁面加載性能。
一些包將它們的ES模塊構(gòu)建作為許多單獨(dú)的文件相互導(dǎo)入。例如,lodash-es有超過600個(gè)內(nèi)部模塊!當(dāng)我們從'lodash-es'導(dǎo)入{debounce}時(shí),瀏覽器會(huì)同時(shí)發(fā)出600多個(gè)HTTP請(qǐng)求!盡管服務(wù)器在處理這些請(qǐng)求時(shí)沒有問題,但大量的請(qǐng)求會(huì)在瀏覽器端造成網(wǎng)絡(luò)擁塞,導(dǎo)致頁面加載明顯變慢。
通過將lodash-es預(yù)綁定到單個(gè)模塊中,我們現(xiàn)在只需要一個(gè)HTTP請(qǐng)求!
自動(dòng)依賴發(fā)現(xiàn)
如果沒有找到現(xiàn)有的緩存,Vite會(huì)抓取你的源代碼,并自動(dòng)發(fā)現(xiàn)依賴項(xiàng)導(dǎo)入(即:希望從node_modules解析的“裸導(dǎo)入”),并使用這些發(fā)現(xiàn)的導(dǎo)入作為預(yù)綁定包的入口點(diǎn)。預(yù)綁定是用esbuild執(zhí)行的,所以它通常非常快。
在服務(wù)器已經(jīng)啟動(dòng)之后,如果在緩存中沒有遇到新的依賴項(xiàng)導(dǎo)入,Vite將重新運(yùn)行dep綁定進(jìn)程并重新加載頁面。
Monorepos and Linked Dependencies
在monorepo設(shè)置中,一個(gè)依賴項(xiàng)可能是來自同一回購(gòu)協(xié)議的鏈接包。Vite自動(dòng)檢測(cè)沒有從node_modules解析的依賴項(xiàng),并將鏈接的dep視為源代碼。它不會(huì)嘗試?yán)壉绘溄拥膁ep,而是會(huì)分析被鏈接的dep的依賴列表。
Customizing the Behavior
默認(rèn)的依賴項(xiàng)發(fā)現(xiàn)啟發(fā)式可能并不總是可取的。如果你想顯式地從列表中包含/排除依賴項(xiàng),使用optimizeDeps配置選項(xiàng)。
optimizeDeps的典型用例。包括或optimizeDeps。當(dāng)您有一個(gè)不能直接在源代碼中發(fā)現(xiàn)的導(dǎo)入時(shí),就可以排除。例如,導(dǎo)入可能是插件轉(zhuǎn)換的結(jié)果。這意味著Vite無法在初始掃描時(shí)發(fā)現(xiàn)導(dǎo)入-它只能在瀏覽器請(qǐng)求文件并進(jìn)行轉(zhuǎn)換后發(fā)現(xiàn)它。這將導(dǎo)致服務(wù)器在啟動(dòng)后立即重新綁定。
include和exclude都可以用來處理這個(gè)問題。如果依賴項(xiàng)很大(包含很多內(nèi)部模塊)或者是CommonJS,那么你應(yīng)該包含它;如果依賴項(xiàng)很小,并且已經(jīng)是有效的ESM,則可以排除它,讓瀏覽器直接加載它。
Caching
文件系統(tǒng)緩存
在node_modules/.Vite中緩存預(yù)綁定的依賴項(xiàng)。它根據(jù)幾個(gè)源來決定是否需要重新運(yùn)行預(yù)綁定步驟:
您的package.json中的依賴項(xiàng)列表
包管理器鎖定文件,例如package-lock.json,yarn.lock,或pnpm-lock.yaml。
只有當(dāng)上面的一個(gè)步驟發(fā)生變化時(shí),才需要重新運(yùn)行預(yù)捆綁步驟。
如果出于某些原因,您想要強(qiáng)制Vite重新綁定deps,您可以使用--force命令行選項(xiàng)啟動(dòng)dev服務(wù)器,或者手動(dòng)刪除node_modules/.vite緩存目錄。
瀏覽器緩存
解析后的依賴請(qǐng)求通過HTTP頭max-age=31536000強(qiáng)緩存,不可變,以提高在開發(fā)期間的頁面重載性能。一旦緩存,這些請(qǐng)求將永遠(yuǎn)不會(huì)再到達(dá)開發(fā)服務(wù)器。如果安裝了不同的版本(反映在包管理器的lockfile中),則附加的版本查詢會(huì)自動(dòng)使它們失效。如果你想通過本地編輯來調(diào)試依賴項(xiàng),你可以:
通過瀏覽器devtools的Network選項(xiàng)卡暫時(shí)禁用緩存;
重啟Vite dev server,使用--force標(biāo)志重新捆綁deps;
重新加載頁面。
