純前端實(shí)現(xiàn)發(fā)布新版本主動(dòng)檢測(cè)更新提醒方案
前言
前端項(xiàng)目發(fā)布新版本后,若用戶(hù)已打開(kāi)頁(yè)面或?yàn)g覽器掛在后臺(tái),由于單頁(yè)應(yīng)用 (SPA) 的機(jī)制,頁(yè)面不會(huì)主動(dòng)刷新,導(dǎo)致用戶(hù)一直停留在舊版本,無(wú)法使用新功能或遇到已修復(fù)的 Bug
那在開(kāi)發(fā)過(guò)程中很容易遇到過(guò)這種問(wèn)題,當(dāng)我把前端寫(xiě)好的新版本的代碼進(jìn)行打包上傳,這個(gè)動(dòng)作已經(jīng)進(jìn)行了版本更新了,但是用戶(hù)在訪問(wèn)舊版本網(wǎng)頁(yè)時(shí)如果沒(méi)有點(diǎn)擊刷新,根本不知道已經(jīng)上新了新版本,而且如果新版本已經(jīng)取消了某個(gè)功能,但用戶(hù)用舊版本進(jìn)行提交必然會(huì)出錯(cuò)
那么就需要一個(gè)主動(dòng)檢測(cè)版本更新的功能提醒用戶(hù)更新了
效果

實(shí)現(xiàn)過(guò)程
1. 構(gòu)建階段:在打包時(shí)生成一個(gè)包含當(dāng)前時(shí)間戳的唯一版本標(biāo)識(shí)文件 (version.json)。
2. 部署階段:Nginx 配置該文件禁止緩存,確保前端永遠(yuǎn)獲取到最新?tīng)顟B(tài)。
3. 運(yùn)行階段:前端代碼通過(guò)輪詢(xún)和頁(yè)面可見(jiàn)性檢測(cè),對(duì)比本地與服務(wù)器的版本號(hào)。
實(shí)現(xiàn)邏輯如下

構(gòu)建腳本改造 (生成版本號(hào))
我們需要在每次 npm run build 時(shí),在輸出目錄(通常是 dist 或 public)生成一個(gè) version.json。
在項(xiàng)目根目錄新建腳本文件 generate-version.js:
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
// 獲取當(dāng)前模塊的路徑
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// 定義版本號(hào)
const versionInfo = {
version: Date.now(),
releaseTime: new Date().toLocaleString()
};
// 確定輸出路徑
const outputDir = path.join(__dirname, 'public');
// 先寫(xiě)入 public 目錄,打包時(shí)會(huì)自動(dòng)復(fù)制到 dist
const filePath = path.join(outputDir, 'version.json');
// 寫(xiě)入文件
fs.writeFileSync(filePath, JSON.stringify(versionInfo, null, 2));
console.log(`? [Version] 版本文件已生成: ${filePath}`);
console.log(`? [Version] 當(dāng)前版本標(biāo)識(shí): ${versionInfo.version}`);前端自動(dòng)檢測(cè)邏輯
在項(xiàng)目的主入口文件(如 src/App.vue, src/App.jsx, src/main.js)中引入以下邏輯。
/**
* 前端版本自動(dòng)檢測(cè)模塊
*/
// 存儲(chǔ)本地版本號(hào)
let localHash:any = null;
// 檢測(cè)間隔 (毫秒),建議 60秒 或 5分鐘
const CHECK_INTERVAL = 5 * 1000;
async function checkAppVersion() {
try {
// 1. 請(qǐng)求 version.json
// 必須加上時(shí)間戳參數(shù) t=... 防止瀏覽器緩存這個(gè) GET 請(qǐng)求本身
const res = await fetch(`/version.json?t=${Date.now()}`);
if (!res.ok) throw new Error('Version file not found');
const data = await res.json();
const serverHash = data.version;
// 2. 首次加載,只記錄不比對(duì)
if (!localHash) {
localHash = serverHash;
console.log(`-----------------------[Updater] 當(dāng)前版本已鎖定-----------------------: ${localHash}`);
return;
}
// 3. 比對(duì)版本
if (serverHash !== localHash) {
console.log(`-----------------[Updater] 檢測(cè)到新版本------------------------: ${serverHash} (當(dāng)前: ${localHash})`);
showUpdateNotification();
}
console.log(`----------------------[Test] 執(zhí)行檢測(cè)-----------------------: ${localHash}`);
} catch (err) {
// 靜默失敗,不打擾用戶(hù) (可能是網(wǎng)絡(luò)波動(dòng))
console.warn('---------------------[Updater] 版本檢測(cè)失敗:--------------------------', err);
}
}
function showUpdateNotification() {
import('element-plus').then(({ ElMessageBox }) => {
ElMessageBox.confirm(
'系統(tǒng)檢測(cè)到有新版本發(fā)布,請(qǐng)點(diǎn)擊"確定"刷新頁(yè)面以獲取最新功能。',
'版本更新提示',
{
confirmButtonText: '立即刷新',
cancelButtonText: '稍后再說(shuō)',
type: 'warning',
center: true,
modal: false
}
).then(() => {
window.location.reload(true); // true 表示強(qiáng)制從服務(wù)器重載
}).catch(() => {
// 用戶(hù)點(diǎn)擊取消,不做任何操作
});
});
}
// --- 啟動(dòng)檢測(cè)監(jiān)聽(tīng) ---
// 1. 啟動(dòng)定時(shí)輪詢(xún)
setInterval(checkAppVersion, CHECK_INTERVAL);
// 2. 智能監(jiān)聽(tīng):當(dāng)用戶(hù)切換標(biāo)簽頁(yè)回來(lái)時(shí),立即檢查一次
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'visible') {
checkAppVersion();
}
});
// 3. 初始化檢查
checkAppVersion();修改 package.json:

總結(jié)
到此這篇關(guān)于純前端實(shí)現(xiàn)發(fā)布新版本主動(dòng)檢測(cè)更新提醒方案的文章就介紹到這了,更多相關(guān)前端主動(dòng)檢測(cè)更新提醒內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
網(wǎng)頁(yè)禁止鼠標(biāo)左右鍵功能的簡(jiǎn)單代碼
本篇文章介紹與演示網(wǎng)頁(yè)禁止鼠標(biāo)左右鍵的實(shí)例代碼,需要的朋友可以參考一下2013-06-06
javascript實(shí)現(xiàn)簡(jiǎn)單倒計(jì)時(shí)效果
這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)倒計(jì)時(shí)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
微信小程序ajax實(shí)現(xiàn)請(qǐng)求服務(wù)器數(shù)據(jù)及模版遍歷數(shù)據(jù)功能示例
這篇文章主要介紹了微信小程序ajax實(shí)現(xiàn)請(qǐng)求服務(wù)器數(shù)據(jù)及模版遍歷數(shù)據(jù)功能,結(jié)合實(shí)例形式分析了微信小程序ajax調(diào)用及模板wx:for循環(huán)列表渲染相關(guān)操作技巧,需要的朋友可以參考下2017-12-12
javascript正則表達(dá)式之分組概念與用法實(shí)例
這篇文章主要介紹了javascript正則表達(dá)式之分組概念與用法,結(jié)合實(shí)例形式分析了javascript正則表達(dá)式分組的功能、定義與使用方法,需要的朋友可以參考下2016-06-06
一文帶你徹底搞定JavaScript中字符串轉(zhuǎn)駝峰問(wèn)題
前端小伙伴們,有沒(méi)有被命名規(guī)范逼瘋過(guò),今天咱們就用5步徹底搞定字符串轉(zhuǎn)駝峰的問(wèn)題,以后再也不用手動(dòng)改命名啦,快跟隨小編一起學(xué)習(xí)一下吧2025-05-05
Javascript圖像處理—平滑處理實(shí)現(xiàn)原理
這里直接引用OpenCV 2.4+ C++ 平滑處理和OpenCV 2.4+ C++ 邊緣梯度計(jì)算的相關(guān)內(nèi)容平滑也稱(chēng)模糊, 是一項(xiàng)簡(jiǎn)單且使用頻率很高的圖像處理方法,需要了解的朋友可以參考下2012-12-12
Firefox中通過(guò)JavaScript復(fù)制數(shù)據(jù)到剪貼板(Copy to Clipboard 跨瀏覽器版)
這篇文章主要介紹了irefox中通過(guò)JavaScript復(fù)制數(shù)據(jù)到剪貼板的方法,可以跨瀏覽器使用,大家可以使用看看2013-11-11

