Vue<前端页面版本检测> [复制链接]
发表于 7 天前 | 显示全部楼层 |阅读模式
🧑‍💻 写在开头

点赞 + 收藏 === 学会🤣🤣🤣
为什么须要版本检测

1. 办理欣赏器缓存题目


  • 静态资源缓存:欣赏器会缓存 JS、CSS 等静态资源,用户大概继承利用旧版本
  • 用户体验影响:用户无法及时获取新功能,导致功能缺失或操纵非常
2. 保障功能同等性


  • 功能同步:确保全部效户都能利用最新的功能和修复
  • 数据同等性:克制因版本差异导致的数据不同等题目
3. 提拔用户体验


  • 主动提示:在新版本发布后主动关照用户更新
  • 无缝升级:镌汰用户手动革新页面的需求
版本检测核心思绪


团体架构

构建阶段 → 版本文件天生 → 运行时检测 → 版本对比 → 用户提示
技能实现要点

1. 版本标识天生


  • 构建时天生:每次打包时天生唯一的版本标识
  • 时间戳方案:利用时间戳确保每次构建版本号唯一
2. 版本文件摆设


  • JSON 格式:将版本信息生存为 version.json 文件
  • 静态访问:通过 HTTP 哀求可直接访问版本文件
3. 客户端检测机制


  • 定时轮询:定期查抄服务器版本文件
  • 版本对比:比力当地缓存版本与服务器版本
  • 智能提示:仅在版本不同等时提示用户
版本检测实现步调

步调一:构建版本文件天生脚本

创建 build-version.js 文件:
  1. // build-version.js (自动生成版本文件脚本)
  2. const fs = require('fs')
  3. const path = require('path')
  4. // 方案A:使用时间戳作为版本标识(最简单,确保每次打包唯一)
  5. const version = new Date().getTime().toString()
  6. // 版本文件内容
  7. const versionJson = {
  8.   version: version,
  9.   updateTime: new Date().toLocaleString() // 可选:添加更新时间,便于排查
  10. }
  11. // 写入version.json文件(项目根目录)
  12. const versionPath = path.resolve(__dirname, 'public', 'version.json')
  13. fs.writeFileSync(versionPath, JSON.stringify(versionJson, null, 2), 'utf-8')
  14. console.log(`✅ 自动生成版本文件成功,版本号:${version}`)
复制代码
步调二:修改构建下令

在 package.json 中修改构建下令:
  1. {
  2.   "scripts": {
  3.     "build:prod": "node build-version.js && vue-cli-service build"
  4.   }
  5. }
复制代码
步调三:设置 Vue 构建过程

在 vue.config.js 中添加版本文件复制设置:
  1. chainWebpack(config) {
  2.   // ... 其他配置
  3.   
  4.   // 复制 version.json 到 dist 目录
  5.   config.plugin('copy')
  6.     .tap(args => {
  7.       const hasVersionJson = args[0].some(item => item.from === 'version.json')
  8.       if (!hasVersionJson) {
  9.         args[0].push({
  10.           from: path.resolve(__dirname, 'public/version.json'),
  11.           to: path.resolve(__dirname, 'dist/version.json')
  12.         })
  13.       }
  14.       return args
  15.     })
  16. }
复制代码
步调四:实现版本检测工具类

创建 src/utils/versionUpdate.js:
  1. // src/utils/versionUpdate.js
  2. import { Notification } from 'element-ui'
  3. /**
  4. * 版本更新检测工具类(仅生产环境启用轮询,内置环境判断)
  5. */
  6. class VersionUpdate {
  7.   constructor(options = {}) {
  8.     this.config = {
  9.       versionFileUrl: '/version.json', // 版本文件地址
  10.       localVersionKey: 'cmpVersion', // 本地存储的版本号key
  11.       disableFetchCache: true, // 禁用Fetch缓存
  12.       pollInterval: 5 * 60 * 1000, // 5分钟轮询一次
  13.       hasNotified: false // 是否已提醒过用户有新版本
  14.     }
  15.     Object.assign(this.config, options)
  16.     // 定时轮询定时器
  17.     this.pollTimer = null
  18.     // 识别当前环境(Vue CLI 4 自动注入的环境变量)
  19.     this.isProduction = process.env.NODE_ENV === 'production'
  20.   }
  21.   /**
  22.    * 核心方法:执行版本检测
  23.    */
  24.   async checkVersion(isInit = false) {
  25.     try {
  26.       if (this.config.hasNotified) return false
  27.       const localVersion = localStorage.getItem(this.config.localVersionKey) || ''
  28.       const fetchOptions = {}
  29.       if (this.config.disableFetchCache) {
  30.         fetchOptions.cache = 'no-cache'
  31.       }
  32.       const response = await fetch(this.config.versionFileUrl, fetchOptions)
  33.       if (!response.ok) {
  34.         throw new Error(`版本文件请求失败,状态码:${response.status}`)
  35.       }
  36.       const latestVersionInfo = await response.json()
  37.       const serverVersion = latestVersionInfo.version
  38.       if (isInit) {
  39.         this.cacheLatestVersion(serverVersion)
  40.         return true
  41.       }
  42.       if (serverVersion && serverVersion !== localVersion) {
  43.         this.config.hasNotified = true
  44.         console.log('有新版本可用', latestVersionInfo)
  45.         Notification({
  46.           title: '🎉 有新版本可用',
  47.           dangerouslyUseHTMLString: true,
  48.           message: `<p >建议点击刷新页面,以获取最新功能和修复</p> <p >更新时间:${latestVersionInfo.updateTime}</p>`,
  49.           duration: 0,
  50.           customClass: 'check-version-notify',
  51.           onClick: () => {
  52.             this.forceRefreshPage()
  53.           },
  54.           onClose: () => {
  55.             this.resetNotifyFlag()
  56.           }
  57.         })
  58.         return true
  59.       } else {
  60.         // 版本一致时,重置提醒标记,便于后续轮询检测新版本
  61.         this.config.hasNotified = false
  62.         // console.log('当前已是最新版本,已缓存最新版本号')
  63.         return false
  64.       }
  65.     } catch (error) {
  66.       console.warn('版本检测异常,不影响应用运行:', error.message)
  67.       return false
  68.     }
  69.   }
  70.   /**
  71.    * 启动定时轮询检测(内置环境判断:仅生产环境生效)
  72.    */
  73.   async startPolling() {
  74.     // 核心:非生产环境,直接返回,不启动轮询
  75.     if (!this.isProduction) {
  76.       console.log('当前为非生产环境,不启动版本检测轮询')
  77.       return
  78.     }
  79.     // 生产环境:正常启动轮询
  80.     this.stopPolling() // 先停止已有轮询,避免重复启动
  81.     this.checkVersion(true) // 立即执行一次检测
  82.     this.pollTimer = setInterval(() => {
  83.       this.checkVersion()
  84.     }, this.config.pollInterval)
  85.     console.log(`生产环境版本轮询检测已启动,每隔${this.config.pollInterval / 1000 / 60}分钟检测一次`)
  86.   }
  87.   /**
  88.    * 停止定时轮询检测
  89.    */
  90.   stopPolling() {
  91.     if (this.pollTimer) {
  92.       clearInterval(this.pollTimer)
  93.       this.pollTimer = null
  94.       console.log('版本轮询检测已停止')
  95.     }
  96.   }
  97.   /**
  98.    * 重置提醒标记
  99.    */
  100.   resetNotifyFlag() {
  101.     this.config.hasNotified = false
  102.   }
  103.   // 缓存最新版本号
  104.   cacheLatestVersion(version) {
  105.     localStorage.setItem(this.config.localVersionKey, version)
  106.     this.resetNotifyFlag()
  107.   }
  108.   // 强制刷新页面
  109.   forceRefreshPage() {
  110.     window.location.reload(true)
  111.   }
  112. }
  113. const versionUpdateInstance = new VersionUpdate()
  114. export { VersionUpdate, versionUpdateInstance }
  115. export default versionUpdateInstance
复制代码
创建自界说.check-version-notify的版本检测全局样式:

 
  1. // 版本检测通知样式
  2. .check-version-notify{
  3.   border: 3px solid transparent !important;
  4.   cursor: pointer;
  5.   background-color: rgba(255, 255, 255, 0.6) !important;
  6.   backdrop-filter: blur(5px);
  7.   &:hover{
  8.     border: 3px solid $--color-primary !important;
  9.   }
  10.   .el-notification__icon{
  11.     font-size: 18px;
  12.     height: 18px;
  13.   }
  14.   .el-notification__title{
  15.     font-size: 14px;
  16.     line-height: 18px;
  17.   }
  18.   .el-notification__group{
  19.     margin-left: 8px;
  20.   }
  21. }
复制代码
步调五:在应用入口启动版本检测

在 App.vue 或符合的入口文件中启动版本检测:
  1. import versionUpdate from '@/utils/versionUpdate'
  2. ...
  3. mounted() {
  4.   versionUpdate.startPolling()
  5. },
  6. beforeDestroy() {
  7.   versionUpdate.stopPolling()
  8. }
复制代码
如果对您有所资助,欢迎您点个关注,我会定时更新技能文档,各人一起讨论学习,一起进步。



免责声明:如果侵犯了您的权益,请联系站长及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金.

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表