vue3+vite前端打包部署后自动更新

1,184 阅读2分钟

业务场景

前端业务开发完成后进行打包部署,前端自动更新。

解决方案

每次build打包代码时,在 public 目录下生成一个 version.json 版本信息文件,页面刷新或跳转时获取到服务器端的 version.json 中的版本号和浏览器本地缓存的版本号进行对比,实现对版本监控迭代更新,进而实现页面自动更新,获取新的 index.html 文件。

注意:前提是服务器端对 index.html 和 version.json 不缓存。

实现方式

  1. 首先应该禁止浏览器缓存 index.html 和 version.json,设置nginx不缓存的配置。
location / {
    try_files $uri $uri/ /index.html;
    expires -1;
}
  1. 编写 Vite 插件实现打包时自动生成版本信息。插件文件路径:src/utils/updater.js(根据个人习惯选择文件位置)
// updater.js
// const fs = require("fs");
// const path = require("path");
// vite不支持require的引入方式故使用import方式代替,可根据自身项目配置自行选择
import fs from "fs";
import path from "path";

const writeVersion = (versionFile, content) => {
  // 写入文件
  fs.writeFile(versionFile, content, (err) => {
    if (err) throw err;
  });
};

export default (options) => {
  let config;

  return {
    name: "version-update",
    configResolved(resolvedConfig) {
      // 存储最终解析的配置
      config = resolvedConfig;
    },
    buildStart() {
      // 生成版本信息文件路径
      const file = config.publicDir + path.sep + "version.json";
      // 这里使用编译时间作为版本信息
      const content = JSON.stringify({ version: options.version });
      if (fs.existsSync(config.publicDir)) {
        writeVersion(file, content);
      } else {
        fs.mkdir(config.publicDir, (err) => {
          if (err) throw err;
          writeVersion(file, content);
        });
      }
    },
  };
};
  1. vite.config.js对应配置
// 引入updater插件
import updater from "./src/utils/updater";

export default defineConfig((config) => {
  const timestamp = new Date().getTime();
  return {
    // ...
    define: {
      // 定义全局变量
      APP_VERSION: timestamp,
    },
    plugins: [
      // ...
      updater({
        version: timestamp
      }),
    ],
    // ...
  }
})

4.页面跳转或页面刷新时,实时检测版本,检测到新版本自动刷新页面,应该使用前置守卫,在跳转失败报错前检测,跳转失败不会触发后置守卫。

import axios from "axios";
import { showToast } from "vant";
const router = useRouter();

// 这里在路由全局前置守卫中检查版本
router.beforeEach(() => {
  versionCheck();
})

// 版本监控
const versionCheck = async () => {
  if (import.meta.env.MODE === "development") return;
  const response = await axios.get("version.json");
  if (APP_VERSION !== response.data.version) {
    showToast({
      message: "发现新内容,自动更新中...",
      type: "loading",
      duration: 1500,
      onClose: () => {
        window.location.reload();
      },
    });
  }
}

本文参考:Vite + Vue3 实现版本更新检查,实现页面自动刷新_vite版本查看-CSDN博客

注:文章仅供参考,若有更优方案,欢迎各位大佬多多交流指教……

毒鸡汤

突破瓶颈之后,发现还有瓶盖。