跳转至

实现前端版本检测并通知用户刷新

具体实现功能是:前端代码更新后,通知用户系统版本更新进行页面刷新

主要实现思路:

在进行打包后根据生成的app或者chunk-libs文件的hash后缀生成一个版本号输出到version.js文件中。在打包生成index.html中读取HTML内容并获取hash内容,与version.js中的版本号进行对比。

获取hash值并且生成版本号的方法

const fs = require('fs')
const path = require('path')

// 提取HTML中资源哈希值的函数
function extractAndConcatContent(htmlContent) {
  const regex = /(chunk-elementUI|app|chunk-libs)\.([\da-fA-F]+)\.(js|css)/g
  let match
  let result = ''

  // 正确循环处理所有匹配项
  while ((match = regex.exec(htmlContent)) !== null) {
    result += match[2] // 拼接所有哈希值
  }

  return result
}

// 主函数:读取HTML文件并生成版本JSON
function generateVersionFile() {
  const htmlFile = './dist/index.html'

  // 检查HTML文件是否存在
  if (!fs.existsSync(htmlFile)) {
    console.error('index.html未找到')
    process.exit(1)
  }

  try {
    // 读取HTML内容
    const htmlContent = fs.readFileSync(htmlFile, 'utf-8')

    // 提取哈希值
    const hashValue = extractAndConcatContent(htmlContent)

    // 构建版本数据
    const versionData = {
      [`accountNjWeb-version`]: hashValue
    }

    // 计算输出路径
    const outputPath = path.join(__dirname, '..', '..', 'dist', 'version.json')

    // 写入JSON文件
    fs.writeFileSync(outputPath, JSON.stringify(versionData, null, 2))
    console.log('version.json has been created successfully.')
  } catch (err) {
    console.error('生成版本文件失败:', err)
    process.exit(1)
  }
}

// 执行主函数
generateVersionFile()

package.json修改:在执行完build命令后会自动执行postbuild命令

"build": "cross-env NODE_ENV=production env_config=sls node build/build.js",
"postbuild": "node src/utils/generateVersionJson.js",
或者
"build": "cross-env NODE_ENV=production env_config=sls node build/build.js & npm run postbuild",
"postbuild": "node src/utils/generateVersionJson.js",

校验版本号方法

import axios from 'axios'
import Vue from 'vue'

export function extractAndConcatContent(inputString) {
  let match
  let result = ''
  // 正则匹配js文件和css文件的hash值,拼接成字符串
  const regex = /(chunk-elementUI|app|chunk-libs)\.([\da-fA-F]+)\.(js|css)/g
  while ((match = regex.exec(inputString)) !== null) {
    // 提取捕获组中的内容(即中间部分)
    const content = match[2]
    result += content// 拼接内容
  }
  return result
}
export async function isNewVersion() {
  const url = `//${window.location.host}/accountNjWeb/version.json`
  try {
    // 获取version.json值
    const res = await axios.get(url, { headers: { 'Cache-control': 'no-cache' }})
    const newVersion = String(res.data[`accountNjWeb-version`])
    // 获取当前网页拼接的hash值
    const localVersion = extractAndConcatContent(document.documentElement.innerHTML)
    console.log(localVersion)
    // 进行对比,若是不同则提示刷新网页
    if (localVersion !== newVersion) {
      Vue.prototype.$confirm('当前系统有新版本发布,请刷新页面', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '稍后',
        type: 'warning',
        showClose: false,
        closeOnclickModel: false
      }).then(() =>
        window.location.reload(true)
      )
    }
  } catch (error) {
    console.log('获取线上版本号失败utils/version.js', error)
  }
}

在APP.vue中,三分钟校验一次

  mounted(){
    isNewVersion()
    this.judgeVersion = setInterval(() => {
      isNewVersion()
    }, 180000)
  }