前端项目中如何实现版本自动检测和更新提醒

angrybird2332023-09-20Frontend性能优化

在前端项目比如管理后台、H5、官网中等,用户可能会遇到一些问题,项目功能更新了,但是用户也没有刷新页面,导致项目无法正常使用。这个时候,我们就需要实现一个自动检测和更新提醒的功能,提醒用户及时刷新页面,避免无法正常使用新功能。

方式一. 前端和后端配合实现自动检测和更新提醒

  • 后端实现一个接口,返回最新的版本号、更新内容等信息。
  • 前端轮训请求该接口,获取到最新版本号后,判断是否需要更新。
  • 如果需要更新,则弹窗提示用户刷新页面。

方式二. 前端自己查询配置文件或获取项目文件的hash值来判断

  1. 通过请求配置文件来判断 + 在项目中定义一个version.json文件。 + 在打包时,将版本号写入该文件。 + 运行时,读取本地存储的版本号,将本地存储的版本号与当前版本号进行对比,如果版本号不一致,则提示用户更新。
例如:
import axios from 'axios';
axios.get('xxx/version.json')
  .then(res => {
    const serverVersion = res.data.version;
    const localVersion = localStorage.getItem('version');

    if (serverVersion !== localVersion) {
      // 提示用户更新
      alert('有新版本,请刷新页面');
      localStorage.setItem('version', serverVersion);
    }
  })
  .catch(err => {
    console.error(err);
  });
      
  1. 通过获取项目文件的hash值来判断 + 打包时配置打包代码,为打包的文件自动添加hash值 + 新建version-upgrade.js,用于检测项目文件是否更新,并提醒用户刷新

示例代码如下:

vue.config.js

const path = require("path");

function getAssetPath(assetsDir, filePath) {
  return assetsDir ? path.posix.join(assetsDir, filePath) : filePath;
}

chainWebpack: config => {
  const filename = getAssetPath("static", `/js/[name]-[hash].js`);
  config.output.filename(filename).chunkFilename(filename);
},
  

version-upgrade.js


const DURATION = 60 * 1000; // 版本更新检测间隔时间

// 获取app.js 的哈希值
const getAppHash = scripts => {
  let localVersion = "";
  for (let i = 0; i < scripts.length; i++) {
    const src = scripts[i].getAttribute("src");
    if (src && src.indexOf("app-") != -1) {
      // 正则返回中间版本号(如果没有,返回空)
      const regRes = /app-(.*?).js/;
      if (regRes.test(src)) {
        localVersion = regRes.exec(src)[1];
      }
    }
  }
  return localVersion;
};

// 获取本地的app.js版本号
const getLocalHash = () => {
  return getAppHash(document.getElementsByTagName("script"));
};

// 获取线上的app.js版本号
const getLastestHash = () => {
  return new Promise((resolve, reject) => {
    const href = window.location.href;
    // 加上时间戳,防止缓存
    fetch(href + "?time=" + Date.now())
      .then(async res => {
        const html = await res.text(); // 转成字符串判断
        const doc = new DOMParser().parseFromString(html, "text/html");
        const newVersion = getAppHash(doc.getElementsByTagName("script"));
        resolve(newVersion);
      })
      .catch(err => {
        console.log("获取版本号失败", err);
        reject(err);
      });
  });
};

// 定时执行,自动更新逻辑(每10s检测一次)

export const autoRefresh = () => {
  setInterval(async () => {
    // 本地
    const localVersion = getLocalHash();
    // 线上
    const newVersion = await getLastestHash();
    // 如果不一样,就进行刷新
    if (localVersion !== newVersion) {
      console.log("有新版本,自动刷新页面");
      window.location.reload(true);
    }
  }, DURATION);
};

  • 在App.vue中引入并执行autoRefresh方法.
import { autoRefresh } from "@/utils/version-upgrade";

export default {
  mounted() {
    const is_localhost = window.location.hostname === "localhost";
    !is_localhost && autoRefresh();
  }
};

最后更新时间 1/7/2025, 6:24:06 AM