前言
当我们的系统重新打包部署后,在线的用户还会一直停留在旧版本的系统上,可能功能存在差异。所以,当系统升级部署后,要提示在线用户发现系统新版本,让用户选择性的是否刷新页面。
前端技术
vue3+ts+element plus+vite4
解决办法
项目每次打包完成后,script中的src引入的js的hash值会变化,也就是之前的版本和新版本的js名称不一样,这样我们可以轮询获取js的名称去判断是否有版本更新。
代码实现
let lastSrcs:null | Array<string>=null
const scriptReg=/<script.*?src="(.*?)">/g
//获取script
async function getScripts(){
const html:string=await fetch('/?timestamp='+Date.now()).then(res=>{
res.text()
})
scriptReg.lastIndex=0 //从第0个开始
const result=[]
while((match=scriptReg.exec(html))){
result.push(match[1])
}
return result
}
//检测更新
async function update(){
const newScript=await getScripts();
if(!lastSrcs){
lastSrcs=newScript
return false
}
let result=false //默认不更新
if(lastSrcs.length!==newScript.length){
result=true
}else{
for(let i=0;i<lastSrcs.length;i++){
if(lastSrcs[i]!=newScript[i]){
result=true
break
}
}
}
lastSrcs=newScript
return result
}
let timeInterval:number=3000
//导出一个可以设置间隔的方法
export function setTImeInTerval(millisecond:number){
timeInterval=millisecond
}
//自动检测函数
let _setTimeout:any=null
function auto(){
_setTimeout=setTimeout(async ()=>{
const isUpdate=await update()
if(isUpdate){
return ElMessageBox.confirm("检测到系统有更新,是否刷新页面?",'提示',{
confirmButtonText:"确定",
cancelButtonText:"取消",
type:"warning",
}).then(()=>{
location.reload()
})
}
auto()
},timeInterval)
}
//执行自动检测函数
if(import.meta.env.MODE==='production'){
auto;
}
使用方法
直接在入口文件引入即可。
import '@/utils/auto-update'
后续优化
当用户的视角离开页面的时候停止发送请求,用户回到页面视角继续请求,可以参考我以前发的文章。
import activeView from './activeView'
//执行自动检测函数
if(import.meta.env.MODE==='production'){
auto()
activeView(()=>{
auto()
},()=>{
clearTimeout(_setTimeout)
})
}