Vite作為Vue3主推構(gòu)建框架,在性能上跟webpack有很大沖擊,并且在開發(fā)圈占有的比重越來越大。文檔說得很詳細(xì),今天只是針對(duì)前端面試常問到的內(nèi)容做一個(gè)篩選總結(jié),也方便不熟悉的同學(xué)快速了解。
一、優(yōu)勢(shì)
或者說為什么選擇了Vite,在瀏覽器支持 ES 模塊之前,JavaScript 并沒有提供原生機(jī)制讓開發(fā)者以模塊化的方式進(jìn)行開發(fā)。這也正是我們對(duì) “打包” 這個(gè)概念熟悉的原因:使用工具抓取、處理并將我們的源碼模塊串聯(lián)成可以在瀏覽器中運(yùn)行的文件。
這種處理有個(gè)弊端,就是項(xiàng)目越大,處理的文件越多,速度就越慢,Vite 旨在利用生態(tài)系統(tǒng)中的新進(jìn)展解決上述問題:瀏覽器開始原生支持 ES 模塊,且越來越多 JavaScript 工具使用編譯型語(yǔ)言編寫。
Vite 以 原生 ESM 方式提供源碼。所以它真正實(shí)現(xiàn)的是:讓瀏覽器接管了打包程序的部分工作:Vite 只需要在瀏覽器請(qǐng)求源碼時(shí)進(jìn)行轉(zhuǎn)換并按需提供源碼。根據(jù)情景動(dòng)態(tài)導(dǎo)入代碼,即只在當(dāng)前屏幕上實(shí)際使用時(shí)才會(huì)被處理。
既然有優(yōu)勢(shì),下面就來細(xì)說一下Vite哪些功能造就了它的優(yōu)勢(shì)。
二、功能
1、npm依賴解析和預(yù)構(gòu)建
import { someMethod } from 'my-dep'
原生 ES 導(dǎo)入不支持,但是ViteVite 將會(huì)檢測(cè)到所有被加載的源文件中的此類裸模塊導(dǎo)入,并執(zhí)行以下操作:
- 預(yù)構(gòu)建 它們可以提高頁(yè)面加載速度,并將 CommonJS / UMD 轉(zhuǎn)換為 ESM 格式。預(yù)構(gòu)建這一步由 esbuild 執(zhí)行,這使得 Vite 的冷啟動(dòng)時(shí)間比任何基于 JavaScript 的打包器都要快得多。
- 重寫導(dǎo)入為合法的 URL,例如
/node_modules/.vite/deps/my-dep.js?v=f3sf2ebd以便瀏覽器能夠正確導(dǎo)入它們。
2、模塊熱替換
Vite 提供了一套原生 ESM 的 HMR API。 具有 HMR 功能的框架可以利用該 API 提供即時(shí)、準(zhǔn)確的更新,而無需重新加載頁(yè)面或清除應(yīng)用程序狀態(tài)。
3、其他
- Vite天然支持引入
.ts文件; - 插件支持Vue,單文件支持有@vitejs/plugin-vue,JSX文件有@vitejs/plugin-vue-jsx;
- css支持import引入以及對(duì).scss、.less等內(nèi)置支持,不需要特地去安裝什么插件;
- 支持靜態(tài)資源引入,像img、js文件等;
- 支持JSON引入;
- Glob導(dǎo)入
- 動(dòng)態(tài)導(dǎo)入
還有很多Vite支持的功能,這里就不在展開說了。下面來說下它的使用吧。
三、使用
1、插件
在vite.config.js中配置
import vitePlugin from 'vite-plugin-feature'
import rollupPlugin from 'rollup-plugin-feature'
export default defineConfig({
plugins: [vitePlugin(), rollupPlugin()],
})
2、配置
默認(rèn)情況下,開發(fā)服務(wù)器 (dev 命令) 運(yùn)行在 development (開發(fā)) 模式,而 build 命令則運(yùn)行在 production (生產(chǎn)) 模式。
這意味著當(dāng)執(zhí)行 vite build 時(shí),它會(huì)自動(dòng)加載 .env.production 中可能存在的環(huán)境變量,那么你可以通過傳遞 --mode 選項(xiàng)標(biāo)志來覆蓋命令使用的默認(rèn)模式。例如,如果你想為我們假設(shè)的 prev 模式構(gòu)建應(yīng)用:
vite build --mode prev
注意:不管是哪個(gè)環(huán)境,它都會(huì)先加載.env,然后合并對(duì)應(yīng)的 .env.prev配置。
這樣就可以通過配置文件來區(qū)分環(huán)境了,怎么用呢:
// .env.prev文件,一定要在根目錄
VITE_GLOB_API_URL=https://your.domain.com
// 在普通文件里,通過import.meta.env拿到變量
const {VITE_GLOB_API_URL} = import.meta.env;
const host = VITE_GLOB_API_URL + '/api';
export default host;
四、Vite VS webpack
1、使用簡(jiǎn)單,開箱即用
相比Webpack需要對(duì)entry、loader、plugin等進(jìn)行諸多配置,Vite的使用可謂是相當(dāng)簡(jiǎn)單了。
只需執(zhí)行初始化命令,就可以得到一個(gè)預(yù)設(shè)好的開發(fā)環(huán)境,開箱即獲得一堆功能,包括:CSS預(yù)處理、html預(yù)處理、異步加載、分包、壓縮、HMR等。
他使用復(fù)雜度介于Parcel和Webpack的中間,只是暴露了極少數(shù)的配置項(xiàng)和plugin接口,既不會(huì)像Parcel一樣配置不靈活,又不會(huì)像Webpack一樣需要了解龐大的loader、plugin生態(tài),靈活適中、復(fù)雜度適中。
2、開發(fā)環(huán)境和速度提升

針對(duì)開發(fā)環(huán)境中的啟動(dòng)慢問題:
- Vite開發(fā)環(huán)境冷啟動(dòng)無需打包,無需分析模塊之間的依賴,同時(shí)也無需在啟動(dòng)開發(fā)服務(wù)器前進(jìn)行編譯,啟動(dòng)時(shí)還會(huì)使用 esbuild 來進(jìn)行預(yù)構(gòu)建。
- 而 Webpack 啟動(dòng)后會(huì)做一堆事情,經(jīng)歷一條很長(zhǎng)的編譯打包鏈條,從入口開始需要逐步經(jīng)歷語(yǔ)法解析、依賴收集、代碼轉(zhuǎn)譯、打包合并、代碼優(yōu)化,最終將高版本的、離散的源碼編譯打包成低版本、高兼容性的產(chǎn)物代碼,這可滿滿都是 CPU、IO 操作啊,在 Node 運(yùn)行時(shí)下性能必然是有問題。
針對(duì)HMR慢:
- 即使只有很小的改動(dòng),Webpack依然需要構(gòu)建完整的模塊依賴圖,并根據(jù)依賴圖來進(jìn)行轉(zhuǎn)換。
- 而Vite利用了ESM和瀏覽器緩存技術(shù),更新速度與項(xiàng)目復(fù)雜度無關(guān)。
可以看到,如Snowpack、Vite這類面相非打包的構(gòu)建工具,在開發(fā)環(huán)境啟動(dòng)時(shí)只需要啟動(dòng)兩個(gè)Server,一個(gè)用于頁(yè)面加載,一個(gè)用于HMR的Websocket。
當(dāng)瀏覽器發(fā)出原生的ESM請(qǐng)求,Server收到請(qǐng)求只需要編譯當(dāng)前文件后返回給瀏覽器,不需要管理依賴。