前言

当我们重新部署前端项目的时候,如果用户一直停留在页面上并未刷新使用,会存在功能使用差异性的问题,因此,当前端部署项目后,需要提醒用户有去重新加载页面。

技术框架

vue、js、webpack

解决方案

编译项目时动态生成一个记录版本号的文件轮询(20s、自己设定时间)这个文件,判断版本号,有新版本则通知用户刷新页面通过监听visibilitychange事件,在页面隐藏时停止轮询,页面显示立马检测一次更新检测到更新后,停止轮询

(感兴趣的可去看方案二:根据打完包之后生成的script src 的hash值去判断,每次打包都会生成唯一的hash值,只要轮询去判断不一样了,那一定是重新部署了。) 

效果

页面右下角提示更新:

代码实现 

 Step1:在 vue.config.js 实现动态创建版本号文件

if (process.env.VUE_APP_ENV !== "production") {

// 这里我设置的是只在非生产环境自动检测更新(生成version);

// 想要所有环境都自动检测更新,只要写if(process.env.VUE_APP_ENV !== "production")内的内容就好

const { writeFile, existsSync } = require('fs')

// 动态生成版本号

const createVersion = () => {

//检测目录是否存在

if (existsSync('./public')) {

writeFile(`./public/version.json`, `{"version":"${Date.now()}"}`, (err) => {

if (err) {

console.log('写入version.json失败')

console.log(err)

} else {

console.log('写入version.json成功')

}

})

} else {

setTimeout(createVersion, 1000)

}

}

setTimeout(createVersion, 10000)

}

 Step2:在src目录下封装 auto-update.js

/*

* @Description: 自动更新

*/

let currentVersion // 当前版本

let version // 新版本

// const timeData = 60 * 1000 // 检查间隔时间

const timeData = 20 * 1000 // 检查间隔时间

let hidden = false // 页面是否隐藏

let setTimeoutId

let needTip = true // 默认开启提示

// 获取版本号

const getVersion = async () => {

return fetch('/version.json?timestep=' + Date.now()).then((res) => res.json())

}

// 检查更新

const checkUpdate = async () => {

console.log('***************checkUpdate**************')

const currentVersion = sessionStorage.getItem("version")

version = (await getVersion()).version

// 本地没有 version,表示刚进入系统,直接塞值

if (!currentVersion) return sessionStorage.setItem("version", version)

console.log(" ~ file: auto-update.js:19 ~ version:", version)

console.log(" ~ file: auto-update.js:21 ~ currentVersion:", currentVersion)

console.log(" ~ file: auto-update.js:23 ~ Number(version) !== Number(currentVersion):", Number(version) !== Number(currentVersion))

let needRefresh = false

if (Number(version) !== Number(currentVersion)) {

console.log('%c 发现新版本~~~~~~', 'color: red')

needRefresh = true

}

return needRefresh

}

// 自动更新

const autoUpdate = async () => {

setTimeoutId = setTimeout(async () => {

// 页面隐藏了就不检查更新

if (!hidden) {

const willUpdate = await checkUpdate()

console.log(" ~ file: auto-update.js:71 ~ setTimeoutId=setTimeout ~ willUpdate, version:", willUpdate, version)

if (willUpdate && needTip) {

// 延时更新,防止部署未完成用户就刷新空白

setTimeout(()=>{

// ----弹框确认---先简单点弹框确认,可以用注释内的,跳过右下角通知的内容(Step3、4)

// const result = confirm('发现新版本,点击确定更新')

// if (result) {

// sessionStorage.setItem('version', version)

// location.reload() // 刷新当前页

// }

// --------------

//*****右下角通知提示 */

window.dispatchEvent(

new CustomEvent("onmessageUpdate", {

detail: {

msg: "发现系统版本更新,请刷新页面~",

version: version

},

})

)

//******************* */

}, 10000)

needTip = false // 关闭更新提示,防止重复提醒

}

}

console.log(" ~ file: auto-update.js:90 ~ autoUpdate ~ needTip: ", needTip)

if (needTip) {

console.warn('needTip autoUpdate');

autoUpdate()

}

}, timeData)

}

// 停止检测更新

const stop = () => {

if (setTimeoutId) {

clearTimeout(setTimeoutId)

setTimeoutId = ''

}

}

// 开始检查更新

const start = async () => {

// currentVersion = (await getVersion()).version

autoUpdate()

// 监听页面是否隐藏

document.addEventListener('visibilitychange', () => {

hidden = document.hidden

console.log(" ~ file: auto-update.js:64 ~ document.addEventListener ~ hidden, needTip:", hidden, needTip)

// 页面隐藏了就不检查更新。或者已经有一个提示框了,防止重复提示。

if (!hidden && needTip) {

autoUpdate()

} else {

stop()

}

})

}

export default { start }

Step3:编写模板 CnNotify.vue 文件

Step4:app.vue 使用组件CnNotify

 Step5:在 main.js 内使用

// 引入自动更新提醒

import autoUpdate from './auto-update'

// 非生产环境使用

process.env.VUE_APP_ENV !== 'production' && autoUpdate.start()

相关文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: