背景
在用户正在访问单页面网站的情况下,突然发布了新的版本。而由于单页面中路由特性,或浏览器缓存的原因,并不会随着路由变化而重新加载前端资源,此时用户浏览器所运行的脚本,并非是最新的代码,从而可能引发一些问题。因此所引发了思考。如何在后端部署之后,提醒用户系统的版本更新,并且引导用户刷新页面,获取最新资源。
纯前端实现思路
可通过前端接收最新的版本信息,并且与本地的登陆时所保存的版本信息来进行比较,可使用轮训、websocket等技术来完成。
唯一hash值
- hash文件的生成
创建hash.js
文件,生成一个唯一值
用于标识当前版本
const crypto = require('crypto');
const fs = require('fs');
const data = crypto.randomBytes(16).toString('hex');
const hash = crypto.createHash('sha256').update(data).digest('hex');
fs.writeFile('./build/hash.txt', hash, (err) => {
if (err) throw err;
});
修改package.json
下的build
命令
"build": "umi run build && node ./hash.js",
- 判断时机
如果发版是在用户不常用的时间段,可以在浏览器visibility切换的回调 + 路由切换拦截时,这2个时机判断版本号,基本上完全够用了
//app.jsx
import request from 'umi-request';
const getHash = () => {
return request(`/hash.txt`);
};
//umi里getInitialState函数用于项目初始化时获取用户信息,这个时机可以添加逻辑进行判断
export async function getInitialState() {
const data = await getHash();
document.addEventListener('visibilitychange', async () => {
console.log(document.visibilityState);
if (document.visibilityState === 'visible') {
const newdata = await getHash();
if (data !== newdata) {
window.location.reload();
}
}
});
return {
collapsed: false,
hash: data,
userInfo: currentUserResult?.body || {},
};
}
export const layout = ({ location, initialState, setInitialState }) => {
return {
onPageChange: async (location) => {
const data = await getHash();
if (data !== initialState.hash) {
window.location.reload();
}
},
onCollapse: (arg) => {
setInitialState({
...initialState,
collapsed: arg,
});
},
...initialState?.settings,
};
};
纯前端umi项目部署页面自动刷新
原文链接:https://juejin.cn/post/7358665606914277376