前端如何实现自动检测更新

背景

用户在访问单页面网站时,如果生产环境已经发布了新的版本(有功能上的变化),由于单页面中路由特性或浏览器缓存的原因,并不会重新加载前端资源,此时用户浏览器所并非加载是最新的代码,从而可能遇到一些 bug。

部署之后,如何提醒用户版本更新,并引导用户刷新页面呢?

方案

这里用的【轮询】的方式请求index.html文件,从中解析里面的js文件,由于vue打包后每个js文件都有指纹标识,因此对比每次打包后的指纹,分析文件是否存在变动,如果有变动则提示用户更新!

环境:vue3 + ts + vite + element-plus

步骤

1.在utils文件夹下新建auto-update.ts,内容如下

typescript 复制代码
import { ElMessageBox } from 'element-plus'


let lastSrcs: any;  //上一次获取到的script地址
let needTip = true; // 默认开启提示

const scriptReg = /<script.*src=["'](?<src>[^"']+)/gm;

const extractNewScripts = async () => {
    const html = await fetch('/?_timestamp=' + Date.now()).then((resp) => resp.text());
    scriptReg.lastIndex = 0;
    let result = [];
    let match: RegExpExecArray
    while ((match = scriptReg.exec(html) as RegExpExecArray)) {
        result.push(match.groups?.src)
    }
    return result;
}

const needUpdate = async () => {
    const newScripts = await extractNewScripts();
    if (!lastSrcs) {
        lastSrcs = newScripts;
        return false;
    }
    let result = false;
    if (lastSrcs.length !== newScripts.length) {
        result = true;
    }
    for (let i = 0; i < lastSrcs.length; i++) {
        if (lastSrcs[i] !== newScripts[i]) {
            result = true;
            break
        }
    }
    lastSrcs = newScripts;
    return result;
}
const DURATION = 10000;

export const autoRefresh = () => {
    setTimeout(async () => {
        const willUpdate = await needUpdate();
        if (willUpdate) {
            // 延时更新,防止部署未完成用户就刷新空白
            setTimeout(() => {
                ElMessageBox.confirm('检测到页面有内容更新,为了功能的正常使用,是否立即刷新?', '更新提示', {
                    confirmButtonText: '确认',
                    showCancelButton: false,
                    type: 'warning'
                }).then(() => {
                    location.reload();
                })
            }, 30000);
            needTip = false; // 关闭更新提示,防止重复提醒
        }
        if (needTip) {
            autoRefresh();
        }
    }, DURATION)
}
  1. Vite的相关配置
javascript 复制代码
/** 
 * @description vite document address
 * https://vitejs.cn/config/ 
 */
export default xxx = () => {
  return {
    base: './',
    resolve: {
      ...
    },
    server: {
      ...
    },
    build: {
      rollupOptions: {
        output: {
          chunkFileNames: 'js/[hash].js', // 引入文件名的名称
          entryFileNames: 'js/[hash].js', // 包的入口文件名称
          assetFileNames: '[ext]/[hash].[ext]', // 资源文件像 字体,图片等
        }
      }
    }
  }
}
  1. 在入口文件mati.ts中引入autoRefresh,如果是生产环境,则执行autoRefresh方法。
javascript 复制代码
import { autoRefresh } from "@/utils/auto-update"
if (import.meta.env.MODE == 'production') {
  autoRefresh()
}

效果

相关推荐
清汤饺子3 小时前
OpenClaw 本地部署教程 - 从 0 到 1 跑通你的第一只龙虾
前端·javascript·vibecoding
爱吃的小肥羊6 小时前
比 Claude Code 便宜一半!Codex 国内部署使用教程,三种方法任选一!
前端
IT_陈寒7 小时前
SpringBoot项目启动慢?5个技巧让你的应用秒级响应!
前端·人工智能·后端
树上有只程序猿7 小时前
2026低代码选型指南,主流低代码开发平台排名出炉
前端·后端
橙某人7 小时前
LogicFlow 小地图性能优化:从「实时克隆」到「占位缩略块」!🚀
前端·javascript·vue.js
高端章鱼哥8 小时前
为什么说用OpenClaw对打工人来说“不划算”
前端·后端
大脸怪8 小时前
告别 F12!前端开发者必备:一键管理 localStorage / Cookie / SessionStorage 神器
前端·后端·浏览器
Mr_Mao8 小时前
我受够了混乱的 API 代码,所以我写了个框架
前端·api
小徐_23338 小时前
向日葵 x AI:把远程控制封装成 MCP,让 AI 替我远程控制设备
前端·人工智能
boooooooom8 小时前
讲清 Proxy + effect + track/trigger 流程
javascript·vue.js·面试