欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于前端實(shí)現(xiàn)版本更新自動(dòng)檢測(cè)的流程步驟

 更新時(shí)間:2025年03月07日 09:40:23   作者:水煮白菜王  
在現(xiàn)代Web應(yīng)用中,為了提升用戶(hù)體驗(yàn)并確保系統(tǒng)的穩(wěn)定性和一致性,部署前端版本更新后及時(shí)提醒用戶(hù)進(jìn)行頁(yè)面刷新是至關(guān)重要的,所以本文給大家介紹了基于前端實(shí)現(xiàn)版本更新自動(dòng)檢測(cè)的流程步驟,需要的朋友可以參考下

一、應(yīng)用場(chǎng)景

在現(xiàn)代Web應(yīng)用中,為了提升用戶(hù)體驗(yàn)并確保系統(tǒng)的穩(wěn)定性和一致性,部署前端版本更新后及時(shí)提醒用戶(hù)進(jìn)行頁(yè)面刷新是至關(guān)重要的。當(dāng)生產(chǎn)環(huán)境發(fā)布了包含功能變化的新版本時(shí),由于單頁(yè)面(SPA)應(yīng)用的路由特性和瀏覽器緩存機(jī)制,用戶(hù)瀏覽器可能不會(huì)自動(dòng)加載最新的代碼資源,這可能導(dǎo)致用戶(hù)遇到bug或體驗(yàn)到不一致的功能行為。通過(guò)實(shí)現(xiàn)自動(dòng)檢測(cè)機(jī)制來(lái)提醒用戶(hù)版本更新,并引導(dǎo)其刷新頁(yè)面,可以

  1. 避免用戶(hù)使用過(guò)期版本
  2. 確保功能一致性
  3. 減少接口兼容性問(wèn)題
  4. 提高應(yīng)用可靠性

二、實(shí)現(xiàn)原理

2.1 核心檢測(cè)邏輯

通過(guò)對(duì)比構(gòu)建產(chǎn)物的哈希值變化實(shí)現(xiàn)版本檢測(cè):

  • 定時(shí)輪詢(xún):每分鐘檢查靜態(tài)資源變化
  • 哈希對(duì)比:通過(guò)解析HTML中script標(biāo)簽指紋判斷更新
  • 強(qiáng)制刷新:檢測(cè)到更新后提示用戶(hù)刷新頁(yè)面
// 核心對(duì)比邏輯
const isChanged = (oldSet, newSet) => {
  return oldSet.size !== newSet.size || 
         ![...oldSet].every(hash => newSet.has(hash))
}

2.2 實(shí)現(xiàn)優(yōu)勢(shì)

  • 通用性強(qiáng):適用于任意前端框架
  • 無(wú)侵入式檢測(cè):不依賴(lài)構(gòu)建工具配置
  • 用戶(hù)可控:提示框讓用戶(hù)選擇刷新時(shí)機(jī)
  • 精準(zhǔn)檢測(cè):通過(guò)對(duì)比script標(biāo)簽內(nèi)容哈希值
  • 低資源消耗:每分鐘檢測(cè)一次,單次請(qǐng)求性能消耗低

三 、具體實(shí)現(xiàn)

3.1 工程化封裝

// useVersionHash.js 核心實(shí)現(xiàn)
export default function useVersionHash() {
  // 狀態(tài)管理
  const timerUpdate = ref(null)
  let scriptHashes = new Set()

  // 生命周期
  onMounted(() => startTimer())
  onBeforeUnmount(() => stopTimer())

  // 業(yè)務(wù)方法
  const fetchScriptHashes = async () => { /*...*/ }
  const compareScriptHashes = async () => { /*...*/ }
  
  return { compareScriptHashes }
}

3.2 關(guān)鍵方法解析

腳本哈希獲?。?/h4>
const fetchScriptHashes = async () => {
  const html = await fetch('/').then(res => res.text())
  const scriptRegex = /<script(?:\s+[^>]*)?>(.*?)<\/script\s*>/gi
  return new Set(html?.match(scriptRegex) || [])
}

對(duì)比邏輯:

if (scriptHashes.size === 0) {
  // 初始化基準(zhǔn)值
  scriptHashes = newScriptHashes  
} else if (
  scriptHashes.size !== newScriptHashes.size ||
  ![...scriptHashes].every(hash => newScriptHashes.has(hash))
) {
  // 觸發(fā)更新流程
  stopTimer()
  showUpdateDialog()
}

四、全部代碼

4.1 vue3

1、use-version-update.js具體邏輯

// @/utils/use-version-update.js
import { ref, onMounted, onBeforeUnmount } from 'vue'
import { ElMessageBox } from 'element-plus'

let scriptHashes = new Set()
const timerUpdate = ref(null)

export default function useVersionHash() {
  const isProduction = import.meta.env.MODE === 'production'

  const fetchScriptHashes = async () => {
    try {
      const html = await fetch('/').then((res) => res.text())
      const scriptRegex = /<script(?:\s+[^>]*)?>(.*?)<\/script\s*>/gi
      return new Set(html?.match(scriptRegex) || [])
    } catch (error) {
      console.error('獲取腳本哈希失敗:', error)
      return new Set()
    }
  }

  const compareScriptHashes = async () => {
    try {
      const newScriptHashes = await fetchScriptHashes()

      if (scriptHashes.size === 0) {
        scriptHashes = newScriptHashes
      } else if (
        scriptHashes.size !== newScriptHashes.size ||
        ![...scriptHashes].every(hash => newScriptHashes.has(hash))
      ) {
        stopTimer()
        updateNotice()
      }
    } catch (error) {
      console.error('版本檢查失敗:', error)
    }
  }

  const updateNotice = () => {
    ElMessageBox.confirm(
      '檢測(cè)到新版本,建議立即更新以確保平臺(tái)正常使用',
      '更新提示',
      {
        confirmButtonText: '確定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    ).then(() => window.location.reload())
  }

  const startTimer = () => {
    if (!isProduction) return
    timerUpdate.value = setInterval(compareScriptHashes, 60000)
  }

  const stopTimer = () => {
    timerUpdate.value && clearInterval(timerUpdate.value)
  }

  onMounted(startTimer)
  onBeforeUnmount(stopTimer)

  return { compareScriptHashes, updateNotice }
}

2、引入use-version-update.js

// App.vue
import versionUpdatefrom '@/utils/use-version-update.js'
export default {
  setup() {
    const { updateNotice } = versionUpdate()
    return { updateNotice }
  }
}

3、Vite 相關(guān)配置

// vite.config.js
import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    rollupOptions: {
      output: {
         // 主入口文件命名規(guī)則
        entryFileNames: 'js/[name]-[hash:8].js',
        
        // 代碼分割塊命名規(guī)則
        chunkFileNames: 'js/[name]-[hash:8].js',
        
        // 靜態(tài)資源文件命名規(guī)則
        assetFileNames: ({ name }) => {
          const ext = name?.split('.').pop()
          return `assets/${ext}/[name]-[hash:8].[ext]`
        }
      }
    },
    // 啟用文件哈希的manifest生成
    manifest: true
  }
})

也可以將use-version-update寫(xiě)成1JS、TS模塊化,在入口文件中main.ts引入

// use-version-update.ts
export const versionUpdate = () => {
  ... 具體處理邏輯
}

// main.ts
import { versionUpdate} from "@/utils/use-version-update"
if (import.meta.env.MODE == 'production') {
  versionUpdate()
}

4.2 vue2

1、use-version-update.js具體邏輯

/*
 * @Author: baicaiKing
 * @Date: 2025-01-02 13:50:33
 * @LastEditors: Do not edit
 * @LastEditTime: 2025-01-03 09:40:36
 * @FilePath: \code\src\utils\use-version-update.js
 */
// 存儲(chǔ)當(dāng)前腳本標(biāo)簽的哈希值集合
let scriptHashes = new Set();
let timerUpdate = undefined;
export default {
    data() {
        return {
        };
    },
    created() {
    },
    mounted() {
        // 每60秒檢查一次是否有新的腳本標(biāo)簽更新
        if (process.env.NODE_ENV === 'production') { // 只針對(duì)生產(chǎn)環(huán)境
            timerUpdate= setInterval(() => {
                this.compareScriptHashes()
            }, 60000);
        }
    },
    beforeDestroy() {
        clearInterval(timerUpdate);
        timerUpdate = null;
    },
    methods: {
        /**
         * 從首頁(yè)獲取腳本標(biāo)簽的哈希值集合
         * @returns {Promise<Set<string>>} 返回包含腳本標(biāo)簽的哈希值的集合
         */
        async fetchScriptHashes() {
            // 獲取首頁(yè)HTML內(nèi)容
            const html = await fetch('/').then((res) => res.text());
            // 正則表達(dá)式匹配所有<script>標(biāo)簽
            const scriptRegex = /<script(?:\s+[^>]*)?>(.*?)<\/script\s*>/gi;
            // 獲取匹配到的所有<script>標(biāo)簽內(nèi)容
            // const scripts = html.match(scriptRegex) ?? [];
            const scripts = html ? html.match(scriptRegex) || [] : [];
            // 將腳本標(biāo)簽內(nèi)容存入集合并返回
            return new Set(scripts);
        },
        /**
         * 比較當(dāng)前腳本標(biāo)簽的哈希值集合與新獲取的集合,檢測(cè)是否有更新
         */
        async compareScriptHashes() {
            // 獲取新的腳本標(biāo)簽哈希值集合
            const newScriptHashes = await this.fetchScriptHashes();

            if (scriptHashes.size === 0) {
                // 初次運(yùn)行時(shí),存儲(chǔ)當(dāng)前腳本標(biāo)簽哈希值
                scriptHashes = newScriptHashes;
            } else if (
                scriptHashes.size !== newScriptHashes.size ||
                ![...scriptHashes].every((hash) => newScriptHashes.has(hash))
            ) {
                // 如果腳本標(biāo)簽數(shù)量或內(nèi)容發(fā)生變化,則認(rèn)為有更新
                console.info('已檢測(cè)到更新文件', {
                    oldScript: [...scriptHashes],
                    newScript: [...newScriptHashes],
                });
                // 清除定時(shí)器
                clearInterval(timerUpdate);
                // 提示用戶(hù)更新
                this.updateNotice();
            } else {
                // 沒(méi)有更新
                console.info('未檢測(cè)到更新時(shí)機(jī)', {
                    oldScript: [...scriptHashes],
                });
            }
        },
        updateNotice() {
            this.$confirm('檢測(cè)到新版本,建議立即更新以確保平臺(tái)正常使用', '更新提示', {
                confirmButtonText: '確定',
                cancelButtonText: '取消(自行刷新)',
                type: 'warning'
            }).then(() => {
                window.location.reload();
            }).catch(() => {
                console.eror('用戶(hù)取消刷新!');

            });
        }
    },

};

2、引入use-version-update.js

// App.vue
import versionUpdate from "@/util/use-version-update.js";
export default {
  name: "app",
  mixins: [versionUpdate],
  data() {
    return {};
  },
};

3、Webpack 相關(guān)配置

// vue.config
module.exports = {
  configureWebpack: {
    output: {
      filename: 'js/[name].[hash].js',
      // filename: 'js/[name].[contenthash].js',
    },
  },
  devServer: {
  },
};

五、注意事項(xiàng)與常見(jiàn)問(wèn)題

5.1 可能出現(xiàn)的問(wèn)題

問(wèn)題現(xiàn)象可能原因解決方案
檢測(cè)不準(zhǔn)確正則匹配失效更新正則表達(dá)式
生產(chǎn)環(huán)境未生效環(huán)境變量配置錯(cuò)誤檢查構(gòu)建配置
跨域請(qǐng)求失敗部署路徑不匹配調(diào)整fetch請(qǐng)求路徑
內(nèi)存泄漏定時(shí)器未正確清除使用WeakRef優(yōu)化

5.2 瀏覽器兼容方案

可結(jié)合Service Worker實(shí)現(xiàn)無(wú)縫更新

// 支持Service Worker的漸進(jìn)增強(qiáng)方案
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js')
    .then(reg => {
      reg.addEventListener('updatefound', () => {
        showUpdateNotification()
      })
    })
}

同時(shí)要確保服務(wù)器配置正確緩存策略,通常Nginx緩存策略默認(rèn)不用打理

以上就是基于前端實(shí)現(xiàn)版本更新自動(dòng)檢測(cè)的流程步驟的詳細(xì)內(nèi)容,更多關(guān)于前端版本更新自動(dòng)檢測(cè)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 小程序識(shí)別身份證,銀行卡,營(yíng)業(yè)執(zhí)照,駕照的實(shí)現(xiàn)

    小程序識(shí)別身份證,銀行卡,營(yíng)業(yè)執(zhí)照,駕照的實(shí)現(xiàn)

    這篇文章主要介紹了小程序識(shí)別身份證,銀行卡,營(yíng)業(yè)執(zhí)照,駕照的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • js實(shí)現(xiàn)下一頁(yè)頁(yè)碼效果

    js實(shí)現(xiàn)下一頁(yè)頁(yè)碼效果

    本文主要介紹了js實(shí)現(xiàn)下一頁(yè)頁(yè)碼效果的實(shí)例,具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧
    2017-03-03
  • ES6實(shí)現(xiàn)圖片切換特效代碼

    ES6實(shí)現(xiàn)圖片切換特效代碼

    這篇文章主要介紹了ES6實(shí)現(xiàn)圖片切換特效代碼,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-01-01
  • 詳解JavaScript中的Map和WeakMap

    詳解JavaScript中的Map和WeakMap

    Map和WeakMap都是ES6中新增的數(shù)據(jù)結(jié)構(gòu),它們的主要區(qū)別在于鍵的作用域和鍵的類(lèi)型,本文就通過(guò)代碼示例給大家詳細(xì)介紹了JavaScript鍵的作用域和類(lèi)型,需要的朋友可以參考下
    2023-08-08
  • JavaScript比較同一天的時(shí)間大小實(shí)例代碼

    JavaScript比較同一天的時(shí)間大小實(shí)例代碼

    在項(xiàng)目開(kāi)發(fā)中,經(jīng)常會(huì)遇到同一天內(nèi)的時(shí)間大小比較,下面小編給大家?guī)?lái)了JavaScript比較同一天的時(shí)間大小實(shí)例代碼,需要的朋友參考下
    2018-02-02
  • 頁(yè)面點(diǎn)擊小紅心js實(shí)現(xiàn)代碼

    頁(yè)面點(diǎn)擊小紅心js實(shí)現(xiàn)代碼

    有時(shí)候我們經(jīng)??吹接行゜log出現(xiàn)一些點(diǎn)擊頁(yè)面出現(xiàn)小紅心的效果,很是喜歡,這里就為大家分享一下代碼直接引用即可
    2018-05-05
  • Javascript點(diǎn)擊按鈕隨機(jī)改變數(shù)字與其顏色

    Javascript點(diǎn)擊按鈕隨機(jī)改變數(shù)字與其顏色

    這篇文章主要介紹了Javascript點(diǎn)擊按鈕隨機(jī)改變數(shù)字和其字體的顏色,實(shí)現(xiàn)后的效果很不錯(cuò),具有一定的參考價(jià)值,有需要的可以參考借鑒,下面來(lái)一起看看。
    2016-09-09
  • JavaScript的設(shè)計(jì)模式經(jīng)典之代理模式

    JavaScript的設(shè)計(jì)模式經(jīng)典之代理模式

    代理模式的定義是把對(duì)一個(gè)對(duì)象的訪(fǎng)問(wèn), 交給另一個(gè)代理對(duì)象來(lái)操作。接下來(lái)通過(guò)本文給大家介紹JavaScript的設(shè)計(jì)模式之代理模式,感興趣的朋友一起學(xué)習(xí)吧
    2016-02-02
  • javaScript封裝的各種寫(xiě)法

    javaScript封裝的各種寫(xiě)法

    這篇文章主要介紹了javaScript封裝的各種寫(xiě)法,通過(guò)列舉優(yōu)缺點(diǎn)和使用場(chǎng)景詳細(xì)介紹了幾種封裝的格式,需要的朋友可以參考下
    2017-08-08
  • 實(shí)現(xiàn)163郵箱的圖標(biāo)功能

    實(shí)現(xiàn)163郵箱的圖標(biāo)功能

    實(shí)現(xiàn)163郵箱的圖標(biāo)功能...
    2007-05-05

最新評(píng)論