Vite+Vue3項目版本更新檢查與頁面自動刷新的實現(xiàn)方案
問題
使用 Vite 對 Vue 項目進(jìn)行打包,對 js 和 css 文件使用了 chunkhash 進(jìn)行了文件緩存控制,但是項目的 index.html 文件在版本頻繁迭代更新時,會存在被瀏覽器緩存的情況。
在發(fā)版后,如果用戶不強制刷新頁面,瀏覽器會使用舊的 index.html 文件,在跳轉(zhuǎn)頁面時會向服務(wù)器端請求了上個版本 chunkhash 的 js 和 css 文件,但此時的文件已經(jīng)在版本更新時已替換刪除了,最終表現(xiàn)為頁面卡頓,控制臺報錯 404。
解決思路
在每次打包生產(chǎn)代碼時,在 public 目錄下生成一個 version.json 版本信息文件,頁面跳轉(zhuǎn)時請求服務(wù)器端的 version.json 中的版本號和瀏覽器本地緩存的版本號進(jìn)行對比,從而監(jiān)控版本迭代更新,實現(xiàn)頁面自動更新,獲取新的 index.html 文件(前提是服務(wù)器端對 index.html 和 version.json 不緩存)。
第一步:配置服務(wù)器,禁止關(guān)鍵文件緩存
要實現(xiàn)版本對比,需確保 index.html 和后續(xù)生成的版本文件 version.json 不被瀏覽器緩存 —— 每次請求均從服務(wù)器獲取最新內(nèi)容。以 Nginx 為例,添加如下配置:
location ~ .*\.(htm|html|json)?$ {
expires -1;
}
第二步:開發(fā) Vite 插件,自動生成版本信息
通過自定義 Vite 插件,在打包時自動在 public 目錄下生成 version.json 文件,記錄當(dāng)前版本標(biāo)識(建議用時間戳,確保每次打包版本號唯一)。 TypeScript 版本插件(src/plugins/versionUpdatePlugin.ts)
// versionUpdatePlugin.ts
import fs from "node:fs"
import path from "node:path"
import type { ResolvedConfig } from "vite"
function writeVersion(versionFile: string, content: string) {
// 寫入文件
fs.writeFile(versionFile, content, (err) => {
if (err) throw err
})
}
export default (version: string | number) => {
let config: ResolvedConfig
return {
name: "version-update",
configResolved(resolvedConfig: ResolvedConfig) {
// 存儲最終解析的配置
config = resolvedConfig
},
buildStart() {
// 生成版本信息文件路徑
const file = config.publicDir + path.sep + "version.json"
// 這里使用編譯時間作為版本信息
const content = JSON.stringify({ version })
if (fs.existsSync(config.publicDir)) {
writeVersion(file, content)
} else {
fs.mkdir(config.publicDir, (err) => {
if (err) throw err
writeVersion(file, content)
})
}
},
}
}
JavaScript 版本插件(src/plugins/versionUpdatePlugin.js)
// versionUpdatePlugin.js
const fs = require("fs")
const path = require("path")
const writeVersion = (versionFile, content) => {
// 寫入文件
fs.writeFile(versionFile, content, (err) => {
if (err) throw err
})
}
export default (options) => {
let config
return {
name: "version-update",
configResolved(resolvedConfig) {
// 存儲最終解析的配置
config = resolvedConfig
},
buildStart() {
// 生成版本信息文件路徑
const file = config.publicDir + path.sep + "version.json"
// 這里使用編譯時間作為版本信息
const content = JSON.stringify({ version: options.version })
if (fs.existsSync(config.publicDir)) {
writeVersion(file, content)
} else {
fs.mkdir(config.publicDir, (err) => {
if (err) throw err
writeVersion(file, content)
})
}
},
}
}
第三步:配置 Vite,注入全局版本變量
在 vite.config.js/ts 中引入上述插件,同時定義全局版本變量 __APP_VERSION__(供前端對比使用),建議用當(dāng)前時間戳作為版本號,確保每次打包版本唯一。
類型聲明(TS 項目必備)
若使用 TypeScript,需在 vite-env.d.ts 或 env.d.ts 中添加全局變量類型聲明,避免類型報錯:
// vite-env.d.ts declare const __APP_VERSION__: string
// vite.config.js or vite.config.ts
export default defineConfig((config) => {
const now = new Date().getTime()
return {
// ...
define: {
// 定義全局變量
__APP_VERSION__: now,
},
plugins: [
// ...
versionUpdatePlugin({
version: now,
}),
],
// ...
}
})
第四步:前端實現(xiàn)版本檢測,觸發(fā)自動刷新
利用 Vue Router 的全局前置守衛(wèi),在每次頁面跳轉(zhuǎn)前檢查版本 —— 對比瀏覽器端全局變量 __APP_VERSION__ 與服務(wù)器端 version.json 中的版本號,若不一致則提示用戶并自動刷新頁面(選擇前置守衛(wèi)是因為跳轉(zhuǎn)失敗不會觸發(fā)后置守衛(wèi),可在報錯前完成檢測)。
const router = useRouter()
// 這里在路由全局前置守衛(wèi)中檢查版本
router.beforeEach(async () => {
await versionCheck()
})
// 版本監(jiān)控
const versionCheck = async () => {
if (import.meta.env.MODE === "development") return
const response = await axios.get("version.json")
if (__APP_VERSION__ !== response.data.version) {
ElMessage({
message: "發(fā)現(xiàn)新內(nèi)容,自動更新中...",
type: "success",
showClose: true,
duration: 1500,
onClose: () => {
window.location.reload()
},
})
}
}
最后
到此這篇關(guān)于Vite+Vue3項目版本更新檢查與頁面自動刷新的實現(xiàn)方案的文章就介紹到這了,更多相關(guān)Vite+Vue3項目版本更新檢查與刷新內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue中Axios添加攔截器刷新token的實現(xiàn)方法
Axios是一款網(wǎng)絡(luò)前端請求框架,本文主要介紹了vue中Axios添加攔截器刷新token的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02
vue項目引入遠(yuǎn)程jweixin-1.2.0.js文件并使用詳解
這篇文章主要介紹了vue項目引入遠(yuǎn)程jweixin-1.2.0.js文件并使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-03-03
Element?Plus的el-tree-select組件懶加載+數(shù)據(jù)回顯詳解
el-tree-select組件是el-tree和el-select的結(jié)合體,他們的原始屬性未被更改,下面這篇文章主要給大家介紹了關(guān)于Element?Plus的el-tree-select組件懶加載+數(shù)據(jù)回顯的相關(guān)資料,需要的朋友可以參考下2022-11-11
vue 實現(xiàn)強制類型轉(zhuǎn)換 數(shù)字類型轉(zhuǎn)為字符串
今天小編就為大家分享一篇vue 實現(xiàn)強制類型轉(zhuǎn)換 數(shù)字類型轉(zhuǎn)為字符串,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11
Vue3中的Teleport與Portal的區(qū)別分析
在現(xiàn)代前端開發(fā)中,特別是使用Vue.js進(jìn)行構(gòu)建時,開發(fā)者常常面臨著如何更有效地管理DOM結(jié)構(gòu)與組件之間的關(guān)系的問題,Vue 3引入了兩個頗具魅力的概念——Teleport和Portal,本文將深入探討這兩者的不同之處,需要的朋友可以參考下2025-01-01
vue-quill-editor插入圖片路徑太長問題解決方法
這篇文章主要介紹了vue-quill-editor插入圖片路徑太長問題解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
解決Vue使用bus總線時,第一次路由跳轉(zhuǎn)時數(shù)據(jù)沒成功傳遞問題
這篇文章主要介紹了解決Vue使用bus總線時,第一次路由跳轉(zhuǎn)時數(shù)據(jù)沒成功傳遞問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07
利用Vue3+Element-plus實現(xiàn)大文件分片上傳組件
在開發(fā)中如果上傳的文件過大,可以考慮分片上傳,分片就是說將文件拆分來進(jìn)行上傳,將各個文件的切片傳遞給后臺,然后后臺再進(jìn)行合并,下面這篇文章主要給大家介紹了關(guān)于利用Vue3+Element-plus實現(xiàn)大文件分片上傳組件的相關(guān)資料,需要的朋友可以參考下2023-01-01
vue如何實現(xiàn)清空this.$route.query的值
這篇文章主要介紹了vue如何實現(xiàn)清空this.$route.query的值,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09

