小工具知识网

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

行业知识

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

2026-11-02 17:28:31 来源:互联网转载

前言

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

技术框架

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 setTimeoutIdlet 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 文件

                      {{ msg }}                      确认刷新        我知道了            export default {  props: {    msg: {      type: String,      default: '',    },    version: {      type: String,      default: '',    },  },  data() {    return {};  },  created() {},  methods: {    // 点击确定更新    onSubmit() {      sessionStorage.setItem('version', this.version) // 存入版本version      location.reload() // 刷新    },    // 关闭    cancle() {      this.$parent.close();    },  },};.cn_notify {  .content {    padding: 20px 0;  }  .footer {    display: flex;    justify-content: center;  }}.versionNotifyStyle {  .el-notification__content {    width: 280px !important;  }}

    Step4:app.vue 使用组件CnNotify

            // 引入CnNotify组件import CnNotify from "@/components/common/CnNotify/index.vue"export default  {  name:  'App',  components: {    CnNotify, // 注册组件  },  mounted() {    this.watchUpdate()  },  methods: {      watchUpdate() {        window.addEventListener("onmessageUpdate", (res) => {          console.log(" ~ file: App.vue:20 ~ window.addEventListener ~ res:", res)          let msg = res.detail.msg,          version = res.detail.version          this.$notify({            title: "版本更新提示",            duration: 0,            position: "bottom-right",            dangerouslyUseHTMLString: true,            message: this.$createElement("CnNotify", {              // 使用自定义组件              ref: "CnNotify",              props: {                msg: msg,                version: version              },            }),            customClass:'versionNotifyStyle', //自定义类名          })        })      },  },}

     Step5:在 main.js 内使用

    // 引入自动更新提醒import autoUpdate from './auto-update'// 非生产环境使用process.env.VUE_APP_ENV !== 'production' && autoUpdate.start()

上一篇:Mac电脑设置hosts的方法

下一篇:宣字的读音与含义深度解析