自学内容网 自学内容网

前端如何在生成环境下实现自动检测更新

实现方式

WebSocket

建立一个WebSocket连接,服务器在发布新版本时通过WebSocket向客户端发送更新通知。

优点:实时性强,能够即时通知客户端更新。
缺点:需要额外的服务器资源来维护WebSocket连接,且可能受到网络延迟和稳定性问题的影响。

轮询检测(或页面跳转时请求)

前端代码定期向服务器发送请求,检查是否有新版本发布。

优点:实现简单,不需要额外的服务器配置。
缺点:可能增加服务器负担,且有一定的延迟和性能开销。

1. 利用打包后重新生成的文件名

### 根据引入的script文件名去比较
main.js引入auto-update.js文件

// 存储上一次获取到的script地址数组  
let lastSrcs = [];  
  
// 正则表达式,用于匹配<script>标签中的src属性;m 表示多行匹配
const scriptReg = /<script.*?src=["'](?<src>[^"']+)/gm;  
  
/**  
 * 从最新页面中提取所有的script链接  
 */  
async function extractNewScripts() {  
    // 通过添加时间戳参数来避免浏览器缓存  
    const html = await fetch(`/?_timestamp=${Date.now()}`).then(resp => resp.text());  
    // 重置正则表达式的lastIndex属性,以确保每次都能从头开始匹配  
    scriptReg.lastIndex = 0;  
    let result = [];  
    let match;  
    // 使用while循环和正则表达式的exec方法查找所有匹配项  
    while ((match = scriptReg.exec(html)) !== null) {  
        // 将匹配到的src属性值添加到结果数组中  
        result.push(match.groups.src);  
    }  
    return result;  
}  
  
/**  
 * 检查是否需要更新页面  
 */  
async function needUpdate() {  
    // 获取最新的script链接数组  
    const newScripts = await extractNewScripts();  
    // 如果是第一次调用,则直接更新lastSrcs并返回false  
    if (lastSrcs.length === 0) {  
        lastSrcs = newScripts;  
        return false;  
    }  
    // 比较新旧script链接数组,检查是否有更新  
    let result = false;  
    if (lastSrcs.length !== newScripts.length) {  
        result = true;  
    } else {  
        for (let i = 0; i < lastSrcs.length; i++) {  
            if (lastSrcs[i] !== newScripts[i]) {  
                result = true;  
                break;  
            }  
        }  
    }  
    // 更新lastSrcs为最新的script链接数组  
    lastSrcs = newScripts;  
    return result;  
}  
  
// 设置自动刷新的时间间隔(毫秒)  
const DURATION = 2000;  
  
/**  
 * 自动刷新页面的函数  
 */  
function autoRefresh() {  
    setTimeout(async () => {  
        // 检查是否需要更新页面  
        const willUpdate = await needUpdate();  
        if (willUpdate) {  
            const result = confirm('页面有更新,点击确定刷新页面');  
            if (result) {  
                location.reload();  
            }  
        }  
        autoRefresh();  
    }, DURATION);  
}  

autoRefresh();

2. 使用版本信息文件

打包在 public 目录下生成一个 version.json 版本信息文件,请求服务器端的 version.json 中的版本号和浏览器本地缓存的版本号进行对比,从而监控版本迭代更新,实现页面自动更新(前提是服务器端对version.json 不缓存)

1. 生成 version.json 文件

  "scripts": {
    "dev": "vite",
    "build": "vite build && node ./src/generateVersion.cjs",
    "preview": "vite preview"
  },

2. 创建 src/generateVersion.cjs 文件

const fs = require('fs');  
const { execSync } = require('child_process');  
  
// 获取 Git 提交哈希作为版本号  
// const version = execSync('git rev-parse --short HEAD').toString().trim(); 
 
const version = Date.now()
  
// 创建 version.json 文件  
const versionInfo = {  
  version: version,  
};  
  
fs.writeFileSync('dist/version.json', JSON.stringify(versionInfo, null, 2), 'utf-8');

3. 请求并对比版本信息

async function checkForUpdates() {
  try {
    // 获取本地缓存的版本信息  
    const cachedVersion = JSON.parse(localStorage.getItem('version')) || {};

    // 请求服务器端的版本信息  
    const response = await fetch('/version.json');
    const serverVersion = await response.json();

    // 对比版本信息  
    if (serverVersion.version !== cachedVersion.version) {
      console.log('New version detected, refreshing the page...');
      localStorage.setItem('version', JSON.stringify(serverVersion));
      location.reload(); // 刷新页面  
    } else {
      console.log('No updates available.');
    }
  } catch (error) {
    console.error('Error checking for updates:', error);
  }
}

原文地址:https://blog.csdn.net/qq_45487080/article/details/142994198

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!