业务功能·

自动更新

如何实现vue项目生产环境的自动更新?

实现

根据打包后生成的文件路径名不同,判断是否存在页面更新

/**
 * 思路:
 * 获取html源码
 * 根据html源码获取所有script的src地址
 * 对比src地址,检验是否有更新
 * 轮循执行
 */

let lastScripts; // 上一次获取到的script地址

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

// 获取最新页面中的script的链接
async function extractNewScripts() {
  // 获取html源码
  const html = await fetch("/?_timestamp=" + Date.now()).then((res) =>
    res.text()
  );
  // 获取所有script的src地址
  scriptReg.lastIndex = 0;
  let result = [];
  let match;
  while ((match = scriptReg.exec(html))) {
    result.push(match.groups.src);
  }
  return result;
}

// 对比src地址,检验是否有更新
async function needUpdate() {
  const newScripts = await extractNewScripts();

  // 记录上一次
  if (!lastScripts) {
    lastScripts = newScripts;
    return false;
  }

  let result = false;

  // 对比长度
  if (lastScripts.length !== newScripts.length) {
    result = true;
  }

  // 依次对比
  for (let i = 0; i < lastScripts.length; i++) {
    if (lastScripts[i] !== newScripts[i]) {
      result = true;
      break;
    }
  }

  lastScripts = newScripts;
  return result;
}

// 轮循时间间隔
const ROTATION_TIME = 3000

// 轮循执行
function autoRefresh() {
  setInterval(async () => {
    const willUpdate = await needUpdate()
    if (willUpdate) {
      const result = window.confirm('页面有更新,点击确定刷新页面')
      if (result) {
        window.location.reload()
      }
    }
  }, ROTATION_TIME);
}

autoRefresh()

演示

首次打包后默认效果:

随意修改内容:

更新内容打包后提示:

刷新后页面更新: