使用vite項(xiàng)目打包資源分配目錄
vite項(xiàng)目打包資源分配目錄
vite項(xiàng)目打包后所有資源都放在了assets文件夾中,像傳統(tǒng)工程一樣分為不同的文件夾,js放js文件夾,css放css文件夾,圖片放img文件夾
vite無論是當(dāng)做是腳手架還是構(gòu)建工具,內(nèi)部實(shí)現(xiàn)原理就是Rollup和esbuild
Rollup會深度影響打包結(jié)果,如何在vite里面配置Rollup,Rollup相關(guān)配置
- vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [
vue(),
],
build: {
rollupOptions:{
output: {
entryFileNames: 'js/[name].js',//入口文件
// entryFileNames: 'js/[name]-[hash].js',//入口文件
chunkFileNames: 'js/[name].js',//分包引入文件
// chunkFileNames: 'js/[name]-[hash].js',//分包引入文件
// assetFileNames: '[ext]/[name]-[hash].[ext]',//靜態(tài)文件
assetFileNames(assetInfo){
console.log(assetInfo)
//文件名稱
if (assetInfo.name.endsWith('.css')) {
return 'css/[name].css'
// return 'css/[name]-[hash].css'
}
//圖片名稱
//定義圖片后綴
const imgExts = ['.png', '.jpg', '.jpeg', '.webp', '.gif', '.svg','.ico']
if(imgExts.some(ext => assetInfo.name.endsWith(ext))){
return 'imgs/[name].[ext]'
// return 'imgs/[name]-[hash].[ext]'
}
//剩余資源文件
return 'assets/[name].[ext]'
// return 'assets/[name]-[hash].[ext]'
}
},
},
},
});
vite打包流程和原理
打包原理
vite利用了ES module這個特性,使用vite運(yùn)行項(xiàng)目時,首先會用esbuild進(jìn)行預(yù)構(gòu)建,將所有模塊轉(zhuǎn)換為es module,不需要對我們整個項(xiàng)目進(jìn)行編譯打包,而是在瀏覽器import某個模塊時,發(fā)送一個HTTP請求去加載文件,vite啟動一個 koa 服務(wù)器攔截這些請求,攔截瀏覽器發(fā)出的請求,根據(jù)請求進(jìn)行按需編譯,然后返回給瀏覽器。
Vite有如下特點(diǎn):
- 快速的冷啟動: No Bundle + esbuild 預(yù)構(gòu)建
- 即時的模塊熱更新: 基于ESM的HMR,同時利用瀏覽器緩存策略提升速度
- 真正的按需加載: 利用瀏覽器ESM支持,實(shí)現(xiàn)真正的按需加載
Vite比Webpack快?
主要體現(xiàn)在啟動很快!
所有模塊都是在請求時才被打包和渲染的,因此自然是無法解決的。
你會發(fā)現(xiàn)第一次請求之后就會快很多。
在生產(chǎn)環(huán)境下的表現(xiàn)
vite生產(chǎn)環(huán)境下,為什么使用rollup打包呢?
- Rollup 是一款 ES Module 打包器, 從作用上來看,Rollup 與 Webpack 非常類似。不過相比于 Webpack,Rollup要小巧的多,打包生成的文件更小。 因?yàn)樾∏?,自然在這種特定的打包環(huán)境下,Rollup的打包速度也要比 Webpack 快很多。
- vite正是基于es module的特性實(shí)現(xiàn)的,所以使用rollup要更合適一些。
vite生產(chǎn)環(huán)境下,為什么不用esbuild打包呢?
- 盡管esbuild的打包速度比rollup更快,但 Vite 目前的插件 API 與使用 esbuild 作為打包器并不兼容,rollup插件api與基礎(chǔ)建設(shè)更加完善,所以在生產(chǎn)環(huán)境vite使用rollup打包會更穩(wěn)定一些。
- 如果后面esbuild基礎(chǔ)建設(shè)與生態(tài)更加完善后,esbuild還是更有優(yōu)勢的。
所以使用vite可能會帶來開發(fā)環(huán)境與生產(chǎn)環(huán)境打包結(jié)果不一致的問題。
啟動項(xiàng)目后,完成加載比較慢?
vite項(xiàng)目的啟動確實(shí)比webpack快,但如果某個界面是首次進(jìn)入,且依賴比較多/比較復(fù)雜的話,那就會比較慢,因?yàn)樗粫σ恍〔糠执a進(jìn)行一些簡單的處理,剩余的工作都交給瀏覽器,以及運(yùn)行時進(jìn)行依賴分析,動態(tài)打包,動態(tài)引入。
慢的主要原因就是vite需要動態(tài)的解析依賴,并打包,以下是解決方案:
- 讓vite在啟動之初就對某些資源進(jìn)行預(yù)打包,盡量避免后續(xù)的動態(tài)打包
- 通過配置vite-plugin-optimize-persist插件,首次加載的時候,依然會很慢,這個是正?,F(xiàn)象,因?yàn)槭状尾寮矡o法知道,哪些依賴需要預(yù)構(gòu)建,是在vite動態(tài)引入資源的時候,將這些資源都記錄下來,自動寫入了package.json中,當(dāng)再次啟動項(xiàng)目的時候,插件會讀取之前他寫入在package.json中的數(shù)據(jù),并告知vite,這樣vite就能對這些資源進(jìn)行預(yù)構(gòu)建了,也就能加快進(jìn)入界面的速度了,但相應(yīng)的啟動速度就會比原來稍微慢一點(diǎn)。有意義?因?yàn)檫@個文件可以重復(fù)利用,后續(xù)啟動和別人使用的時候都會加快打包速度。
Esbuild & Rollup
1、開發(fā)環(huán)境:Esbuild
是一個JavaScript、 Bundler 打包和壓縮工具,它提供了與Webpack、Rollup等工具相似的資源打包能力??梢詫avaScript
預(yù)構(gòu)建:
- 支持commonJS依賴
- 上面提到Vite是基于瀏覽器原生支持ESM的能力實(shí)現(xiàn)的,但要求用戶的代碼模塊必須是ESM模塊,因此必須將commonJs的文件提前處理,轉(zhuǎn)化成 ESM 模塊并緩存入 node_modules/.vite
- 減少模塊和請求數(shù)量(我們常用的lodash工具庫,里面有很多包通過單獨(dú)的文件相互導(dǎo)入,而 lodash-es這種包會有幾百個子模塊,當(dāng)代碼中出現(xiàn) import { debounce } from ‘lodash-es’ 會發(fā)出幾百個 HTTP 請求,這些請求會造成網(wǎng)絡(luò)堵塞,影響頁面的加載。
- Vite 將有許多內(nèi)部模塊的 ESM 依賴關(guān)系轉(zhuǎn)換為單個模塊,以提高后續(xù)頁面加載性能。
- 通過預(yù)構(gòu)建 lodash-es 成為一個模塊,也就只需要一個 HTTP 請求了)
Esbuild優(yōu)點(diǎn):
- 編譯運(yùn)行 VS 解釋運(yùn)行
- 大多數(shù)前端打包工具都是基于 JavaScript 實(shí)現(xiàn)的,大家都知道JavaScript是解釋型語言,邊運(yùn)行邊解釋。而 Esbuild 則選擇使用 Go 語言編寫,該語言可以編譯為原生代碼,在編譯的時候都將語言轉(zhuǎn)為機(jī)器語言,在啟動的時候直接執(zhí)行即可,在 CPU 密集場景下,Go 更具性能優(yōu)勢。
- 多線程 VS 單線程
- JavaScript 本質(zhì)上是一門單線程語言,直到引入 WebWorker 之后才有可能在瀏覽器、Node 中實(shí)現(xiàn)多線程操作。就我對Webpack的源碼理解,其源碼也并未使用 WebWorker 提供的多線程能力。而GO天生的多線程優(yōu)勢。
- 對構(gòu)建流程進(jìn)行了優(yōu)化,充分利用 CPU 資源
2、生產(chǎn)環(huán)境:Rollup
Rollup是基于ESM的JavaScript打包工具。相比于其他打包工具如Webpack,他總是能打出更小、更快的包。
因?yàn)?Rollup 基于 ESM 模塊,比 Webpack 和 Browserify 使用的 CommonJS模塊機(jī)制更高效。
Rollup的亮點(diǎn)在于同一個地方,一次性加載。
能針對源碼進(jìn)行 Tree Shaking(去除那些已被定義但沒被使用的代碼),以及 Scope Hoisting 以減小輸出文件大小提升運(yùn)行性能。
熱更新
通過WebSocket創(chuàng)建瀏覽器和服務(wù)器的通信監(jiān)聽文件的改變,當(dāng)文件被修改時,服務(wù)端發(fā)送消息通知客戶端修改相應(yīng)的代碼,客戶端對應(yīng)不同的文件進(jìn)行不同的操作的更新。
熱更新過程主要分為以下幾步:
- 創(chuàng)建一個websocket服務(wù)端和client文件,啟動服務(wù)
- 通過chokidar監(jiān)聽文件變更
- 當(dāng)代碼變更后,服務(wù)端進(jìn)行判斷并推送到客戶端
- 客戶端根據(jù)推送的信息執(zhí)行不同操作的更新

總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue項(xiàng)目打包解決靜態(tài)資源無法加載和路由加載無效(404)問題
這篇文章主要介紹了vue項(xiàng)目打包,解決靜態(tài)資源無法加載和路由加載無效(404)問題,靜態(tài)資源無法使用,那就說明項(xiàng)目打包后,圖片和其他靜態(tài)資源文件相對路徑不對,本文給大家介紹的非常詳細(xì),需要的朋友跟隨小編一起看看吧2023-10-10
Vue解析剪切板圖片并實(shí)現(xiàn)發(fā)送功能
這篇文章主要介紹了Vue解析剪切板圖片并實(shí)現(xiàn)發(fā)送功能,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2020-02-02
vue如何將導(dǎo)航欄、頂部欄設(shè)置為公共頁面
這篇文章主要介紹了vue如何將導(dǎo)航欄、頂部欄設(shè)置為公共頁面問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-01-01
Vue2利用Axios發(fā)起請求的詳細(xì)過程記錄
有很多時候你在構(gòu)建應(yīng)用時需要訪問一個API并展示其數(shù)據(jù),做這件事的方法有好幾種,而使用基于promise的HTTP客戶端axios則是其中非常流行的一種,這篇文章主要給大家介紹了關(guān)于Vue2利用Axios發(fā)起請求的詳細(xì)過程,需要的朋友可以參考下2021-12-12

