Appearance
项目版本更新提示用户刷新
TIP
在开发过程中,我们经常会遇到项目版本更新,需要用户刷新页面才能看到最新的效果。
方法有很多种:各有利弊
- 使用websocket/sse实现版本检查
- 使用webpack-dev-server实现版本检查
- 使用npm-watch实现版本检查
- 请求接口时传递版本号,后端返回最新版本号,前端判断是否需要刷新
- 使用service worker实现版本检查
- 使用npm-version-check实现版本检查
- 使用打包文件hash实现版本检查
- 使用轮询实现版本检查
我觉得比较好的方法
请求封装自定义请求头,传递版本号,后端返回最新版本号,前端判断是否需要刷新。对服务器压力小,对用户影响小。
WARNING
反正都要请求接口的,带一个版本号怎么了?后端判断一下,返回最新版本号,前端判断一下,需要刷新就刷新,不需要刷新就继续用。轮询?你服务器很牛逼吗,隔一下检测一下版本?吃饱了撑得吗?
javascript
import axios from 'axios';
// 当前前端版本号(可以从package.json或其他配置中获取)
const APP_VERSION = '1.0.0';
// 请求拦截器
axios.interceptors.request.use(config => {
// 在请求头中添加版本号
config.headers['X-App-Version'] = APP_VERSION;
return config;
}, error => {
return Promise.reject(error);
});
// 响应拦截器
axios.interceptors.response.use(response => {
return response;
}, error => {
if (error.response && error.response.status === 426) {
// 版本不匹配,提示用户刷新,这个弹窗可以用其他方式实现,如弹窗、Toast、通知等等
alert('检测到新版本,请刷新页面以获取最新功能!');
}
return Promise.reject(error);
});
import axios from 'axios';
// 当前前端版本号(可以从package.json或其他配置中获取)
const APP_VERSION = '1.0.0';
// 请求拦截器
axios.interceptors.request.use(config => {
// 在请求头中添加版本号
config.headers['X-App-Version'] = APP_VERSION;
return config;
}, error => {
return Promise.reject(error);
});
// 响应拦截器
axios.interceptors.response.use(response => {
return response;
}, error => {
if (error.response && error.response.status === 426) {
// 版本不匹配,提示用户刷新,这个弹窗可以用其他方式实现,如弹窗、Toast、通知等等
alert('检测到新版本,请刷新页面以获取最新功能!');
}
return Promise.reject(error);
});
后端定义一个中间件或者函数都可以,根据业务需求来定。
javascript
const express = require('express');
const app = express();
const CURRENT_VERSION = '1.0.1'; // 后端当前版本
app.use((req, res, next) => {
const clientVersion = req.headers['x-app-version'];
if (clientVersion !== CURRENT_VERSION) {
return res.status(426).json({
code: 426,
message: 'Version mismatch',
currentVersion: CURRENT_VERSION
});
}
next();
});
// 其他路由...
const express = require('express');
const app = express();
const CURRENT_VERSION = '1.0.1'; // 后端当前版本
app.use((req, res, next) => {
const clientVersion = req.headers['x-app-version'];
if (clientVersion !== CURRENT_VERSION) {
return res.status(426).json({
code: 426,
message: 'Version mismatch',
currentVersion: CURRENT_VERSION
});
}
next();
});
// 其他路由...
使用vite-plugin-version
在构建时生成版本信息
安装插件
bash
npm install vite-plugin-version --save-dev
npm install vite-plugin-version --save-dev
配置 vite.config.js
生成版本信息
js
import { defineConfig } from 'vite';
import ViteVersion from 'vite-plugin-version';
export default defineConfig({
plugins: [
ViteVersion({
output: 'src/assets/version.json', // 指定版本文件输出路径
}),
],
});
import { defineConfig } from 'vite';
import ViteVersion from 'vite-plugin-version';
export default defineConfig({
plugins: [
ViteVersion({
output: 'src/assets/version.json', // 指定版本文件输出路径
}),
],
});
构建时会在 src/assets/version.json
生成一个类似如下的文件
json
{
"version": "1.0.0",
"buildTime": "2025-06-14T17:00:00Z"
}
{
"version": "1.0.0",
"buildTime": "2025-06-14T17:00:00Z"
}
前端定时请求版本信息
在 Vue 组件中,设置一个定时任务来轮询请求版本信息文件,并与当前版本进行对比。如果版本不一致,提示用户更新。
获取当前版本并与版本文件对比
在 main.js 或 Vue 组件中,实现版本检测功能。
js
import { ref, onMounted } from 'vue';
const currentVersion = import.meta.env.VITE_APP_VERSION || '1.0.0'; // 读取当前版本号,或者从环境变量中获取
const checkForUpdates = async () => {
try {
const response = await fetch('/src/assets/version.json'); // 请求版本信息文件
const data = await response.json();
if (data.version !== currentVersion) {
showUpdatePrompt();
}
} catch (error) {
console.error('检查更新失败:', error);
}
};
const showUpdatePrompt = () => {
const confirmUpdate = confirm('发现新版本,是否立即更新?');
if (confirmUpdate) {
window.location.reload(); // 刷新页面加载新版本
}
};
onMounted(() => {
setInterval(checkForUpdates, 60000); // 每60秒检查一次版本
checkForUpdates(); // 初始检查一次
});
import { ref, onMounted } from 'vue';
const currentVersion = import.meta.env.VITE_APP_VERSION || '1.0.0'; // 读取当前版本号,或者从环境变量中获取
const checkForUpdates = async () => {
try {
const response = await fetch('/src/assets/version.json'); // 请求版本信息文件
const data = await response.json();
if (data.version !== currentVersion) {
showUpdatePrompt();
}
} catch (error) {
console.error('检查更新失败:', error);
}
};
const showUpdatePrompt = () => {
const confirmUpdate = confirm('发现新版本,是否立即更新?');
if (confirmUpdate) {
window.location.reload(); // 刷新页面加载新版本
}
};
onMounted(() => {
setInterval(checkForUpdates, 60000); // 每60秒检查一次版本
checkForUpdates(); // 初始检查一次
});
这是其中一种实现方法
javascript
// main.js
// 检查版本号
function checkVersion() {
return fetch('/api/version')
.then(response => response.json())
.then(data => {
const latestVersion = data.version
const currentVersion = '1.0.0' // 当前版本号
return { isLatest: latestVersion === currentVersion, latestVersion }
})
.catch(error => {
console.error('版本检查失败:', error)
return { isLatest: true, latestVersion: null } // 默认视为最新版本
})
}
// 显示更新提示(非阻塞)
function showUpdatePrompt(latestVersion) {
const shouldUpdate = confirm(`检测到新版本 ${latestVersion},是否刷新以更新?`)
if (shouldUpdate) {
window.location.reload()
}
}
// 初始化检查
checkVersion().then(({ isLatest, latestVersion }) => {
if (!isLatest && latestVersion) {
// 提示用户更新,但不强制刷新
showUpdatePrompt(latestVersion)
}
})
// main.js
// 检查版本号
function checkVersion() {
return fetch('/api/version')
.then(response => response.json())
.then(data => {
const latestVersion = data.version
const currentVersion = '1.0.0' // 当前版本号
return { isLatest: latestVersion === currentVersion, latestVersion }
})
.catch(error => {
console.error('版本检查失败:', error)
return { isLatest: true, latestVersion: null } // 默认视为最新版本
})
}
// 显示更新提示(非阻塞)
function showUpdatePrompt(latestVersion) {
const shouldUpdate = confirm(`检测到新版本 ${latestVersion},是否刷新以更新?`)
if (shouldUpdate) {
window.location.reload()
}
}
// 初始化检查
checkVersion().then(({ isLatest, latestVersion }) => {
if (!isLatest && latestVersion) {
// 提示用户更新,但不强制刷新
showUpdatePrompt(latestVersion)
}
})