web项目版本更新检测与通知(两个解决方案)

背景:对于web项目常常出现的一个问题是:前端有新版本发布了,用户不能及时知晓,导致继续访问了可能有bug的旧版本。
目的:纯前端实现能够主动通知用户更新版本,确保用户能够及时获得最新的功能和修复的 bug。

此方案基本原理:打包的时候生成随机版本号并保存到环境变量里,在index.html的mate标签注入版本号。通过轮询获取index.html的版本号与本地版本号比较。此方案大部分是在前端实现(前提考虑的就是尽量不依赖服务端来实现),服务端要做的仅仅是配置服务器 不缓存index.html。(欢迎评论区交流、分享更多的方案实现~)

以Vue项目为例,具体实现如下:

vue.config.js:

process.env.VUE_APP_VERSION = Date.now() // 生成随机版本号,赋值到环境变量

index.html:

<meta name="version" content="<%= process.env.VUE_APP_VERSION %>">

checkForUpdate.js:
开启轮询,定义通知样式

let currentVersion = null
let delay = process.env.VUE_APP_ENV === 'development' ? 6 * 1000 : 10 * 1000

function notifyUserAboutUpdate() {
  const updateNotification = document.createElement('div')
  updateNotification.innerText = '新版本已发布,请刷新页面以获取最新内容。'
  updateNotification.style.position = 'fixed'
  updateNotification.style.top = '-45px' // 初始位置在视口上方
  updateNotification.style.width = '100%'
  updateNotification.style.backgroundColor = 'rgba(248, 215, 218, 0.9)'
  updateNotification.style.color = '#721c24'
  updateNotification.style.textAlign = 'center'
  updateNotification.style.height = '45px'
  updateNotification.style.lineHeight = '45px'
  updateNotification.style.zIndex = '9999'
  updateNotification.style.transition = 'top 1s' // 设置过渡效果

  // 定义左右抖动的CSS动画
  const styleSheet = document.createElement('style')
  styleSheet.type = 'text/css'
  styleSheet.innerText = `
    @keyframes shake {
      0%, 100% { transform: translateX(0); }
      25% { transform: translateX(-10px); }
      50% { transform: translateX(10px); }
      75% { transform: translateX(-10px); }
    }
  `
  document.head.appendChild(styleSheet)
  document.body.appendChild(updateNotification)

  // 触发从顶部进入效果
  setTimeout(() => {
    updateNotification.style.top = '0'
  }, 500)
  // 1.5秒后开始左右抖动动画
  setTimeout(() => {
    updateNotification.style.animation = 'shake 1s linear infinite'
  }, 1500)
  // 3.5秒后移除抖动动画
  setTimeout(() => {
    updateNotification.style.animation = ''
  }, 3500)
}

document.addEventListener('DOMContentLoaded', () => {
  currentVersion = document
    .querySelector('meta[name="version"]')
    .getAttribute('content')
  if (window.Worker) {
    const worker = new Worker('/static/js/updateWorker.js')
    worker.postMessage({ currentVersion, delay })

    worker.onmessage = (event) => {
      if (event.data === 'updateAvailable') {
        notifyUserAboutUpdate()
      }
    }
  } else {
    console.error('Web Workers are not supported in this browser.')
  }
})

updateWorker.js:
定义轮询。此示例使用Worker,避免阻塞主进程。

let currentVersion = null
let delay = null
self.onmessage = (event) => {
  currentVersion = event.data.currentVersion
  delay = event.data.delay
  checkForUpdate()
}
function checkForUpdate() {
  fetch('/index.html')
    .then((response) => response.text())
    .then((html) => {
      const versionMatch = html.match(
        /<meta\s+name="version"\s+content="([^"]+)"/
      )
      if (versionMatch) {
        const newVersion = versionMatch[1]
        if (newVersion !== currentVersion) {
          self.postMessage('updateAvailable')
        } else {
          setTimeout(() => {
            checkForUpdate()
          }, delay)
        }
      } else {
        console.error('Version meta tag not found')
      }
    })
    .catch((error) => console.error('Error checking for update:', error))
}

main.js:

import '@/utils/checkForUpdate' // 入口文件引入js

方案二:https://blog.csdn.net/m0_62332650/article/details/143716432

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值