前端项目部署自动检测更新后通知用户刷新页面(前端实现,技术框架vue、js、webpack)——方案一:编译项目时动态生成一个记录版本号的文件

前言

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

技术框架

vue、js、webpack

解决方案

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

前端项目部署自动检测更新后通知用户刷新页面(前端实现,技术框架vue、js、webpack)——方案一:编译项目时动态生成一个记录版本号的文件_第1张图片

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

效果

页面右下角提示更新:

前端项目部署自动检测更新后通知用户刷新页面(前端实现,技术框架vue、js、webpack)——方案一:编译项目时动态生成一个记录版本号的文件_第2张图片

代码实现 

 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)
}

前端项目部署自动检测更新后通知用户刷新页面(前端实现,技术框架vue、js、webpack)——方案一:编译项目时动态生成一个记录版本号的文件_第3张图片

 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()

你可能感兴趣的:(前端,javascript,vue.js)