前端项目中如何实现版本自动检测和更新提醒
在前端项目比如管理后台、H5、官网中等,用户可能会遇到一些问题,项目功能更新了,但是用户也没有刷新页面,导致项目无法正常使用。这个时候,我们就需要实现一个自动检测和更新提醒的功能,提醒用户及时刷新页面,避免无法正常使用新功能。
方式一. 前端和后端配合实现自动检测和更新提醒
- 后端实现一个接口,返回最新的版本号、更新内容等信息。
- 前端轮训请求该接口,获取到最新版本号后,判断是否需要更新。
- 如果需要更新,则弹窗提示用户刷新页面。
方式二. 前端自己查询配置文件或获取项目文件的hash值来判断
- 通过请求配置文件来判断 + 在项目中定义一个version.json文件。 + 在打包时,将版本号写入该文件。 + 运行时,读取本地存储的版本号,将本地存储的版本号与当前版本号进行对比,如果版本号不一致,则提示用户更新。
例如:
import axios from 'axios';
axios.get('xxx/version.json')
.then(res => {
const serverVersion = res.data.version;
const localVersion = localStorage.getItem('version');
if (serverVersion !== localVersion) {
// 提示用户更新
alert('有新版本,请刷新页面');
localStorage.setItem('version', serverVersion);
}
})
.catch(err => {
console.error(err);
});
- 通过获取项目文件的hash值来判断 + 打包时配置打包代码,为打包的文件自动添加hash值 + 新建version-upgrade.js,用于检测项目文件是否更新,并提醒用户刷新
示例代码如下:
vue.config.js
const path = require("path");
function getAssetPath(assetsDir, filePath) {
return assetsDir ? path.posix.join(assetsDir, filePath) : filePath;
}
chainWebpack: config => {
const filename = getAssetPath("static", `/js/[name]-[hash].js`);
config.output.filename(filename).chunkFilename(filename);
},
version-upgrade.js
const DURATION = 60 * 1000; // 版本更新检测间隔时间
// 获取app.js 的哈希值
const getAppHash = scripts => {
let localVersion = "";
for (let i = 0; i < scripts.length; i++) {
const src = scripts[i].getAttribute("src");
if (src && src.indexOf("app-") != -1) {
// 正则返回中间版本号(如果没有,返回空)
const regRes = /app-(.*?).js/;
if (regRes.test(src)) {
localVersion = regRes.exec(src)[1];
}
}
}
return localVersion;
};
// 获取本地的app.js版本号
const getLocalHash = () => {
return getAppHash(document.getElementsByTagName("script"));
};
// 获取线上的app.js版本号
const getLastestHash = () => {
return new Promise((resolve, reject) => {
const href = window.location.href;
// 加上时间戳,防止缓存
fetch(href + "?time=" + Date.now())
.then(async res => {
const html = await res.text(); // 转成字符串判断
const doc = new DOMParser().parseFromString(html, "text/html");
const newVersion = getAppHash(doc.getElementsByTagName("script"));
resolve(newVersion);
})
.catch(err => {
console.log("获取版本号失败", err);
reject(err);
});
});
};
// 定时执行,自动更新逻辑(每10s检测一次)
export const autoRefresh = () => {
setInterval(async () => {
// 本地
const localVersion = getLocalHash();
// 线上
const newVersion = await getLastestHash();
// 如果不一样,就进行刷新
if (localVersion !== newVersion) {
console.log("有新版本,自动刷新页面");
window.location.reload(true);
}
}, DURATION);
};
- 在App.vue中引入并执行autoRefresh方法.
import { autoRefresh } from "@/utils/version-upgrade";
export default {
mounted() {
const is_localhost = window.location.hostname === "localhost";
!is_localhost && autoRefresh();
}
};