切換語言為:簡體

vue3+vite前端打包部署後自動更新

  • 爱糖宝
  • 2024-11-14
  • 2030
  • 0
  • 0

業務場景

前端業務開發完成後進行打包部署,前端自動更新。

解決方案

每次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",
    apply: 'build', // 指明外掛在 'build' 或 'serve' 模式時呼叫
    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(async () => {
  await 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();
      },
    });
  }
}


0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.