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

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

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

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

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

  1. 避免用戶使用過(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í)輪詢:每分鐘檢查靜態(tài)資源變化
  • 哈希對(duì)比:通過(guò)解析HTML中script標(biāo)簽指紋判斷更新
  • 強(qiáng)制刷新:檢測(cè)到更新后提示用戶刷新頁(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è):不依賴構(gòu)建工具配置
  • 用戶可控:提示框讓用戶選擇刷新時(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);
                // 提示用戶更新
                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('用戶取消刷新!');

            });
        }
    },

};

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)文章

最新評(píng)論