單頁面應用(SPA)項目上線後程序刷新一次瀏覽器,來使用新上線資源

解決了什麼問題?

spa項目新上線後,登錄有效期內用戶,能夠立刻使用新上線資源。html

原理:

  • 問:爲何新上線後,不能立刻訪問到新上線資源?
    答:由於設置了瀏覽器緩存;若是不刷新,訪問的仍是緩存的靜態文件。
  • 問:刷新瀏覽器以後,就可使用新上線資源,那在 Vue 項目中究竟是哪一個文件在起做用呢?
    答:歸根結底刷新的是 dist/index.html 文件,此文件引用 manifest 文件(dist/static/js/manifest.[chunkhash].js,該文件包含路由和打包後 js 文件的對應關係);刷新 dist/index.html 文件後,當點擊路由時,根據新的 manifest 文件,按需加載相應的 js 文件。

實現步驟:

  1. 打包時產生一個json文件:static/json/build_str.json
  2. localStorage中存入值:build_str
  3. 每一個路由切換時,從接口得到新打包後json中的字符串,與localStorage中存的上次打包字符串比較,不相同時刷新

此技術方案的好處:

  1. 不須要後端提供接口,前端請求打包後的 JSON 文件
  2. 速度快,請求 JSON 文件耗時短
  3. 用戶無感知

此技術方案實現的代價:

每次切換路由,都要進行一次打包字符串的判斷,增長代碼及請求前端

vue 項目代碼修改的地方:

一、相應目錄下,新建文件:static/json/build_str.json
二、build/build.js 修改:vue

// 將當前時間戳寫入json文件
let json_obj = {"build_str": new Date().getTime().toString()}
fs.writeFile(path.resolve(__dirname, '../static/json/build_str.json'), JSON.stringify(json_obj), function (err) {
    if (err) {
        return console.error(err);
    }
    console.log("打包字符串寫入文件:static/json/build_str.json,成功!");
    realBuild()
})

三、src/main.js 修改:webpack

router.beforeEach((to, from, next) => {
    axios.get('/static/json/build_str.json?v=' + new Date().getTime().toString())
        .then(res => {
            let newBuildStr = res.data.build_str
            let oldBuildStr = localStorage.getItem('build_str') || ''
            if (oldBuildStr !== newBuildStr) {
                console.log('auto refresh')
                localStorage.setItem('build_str', newBuildStr)
                location.reload()
            }
        })
    next()
})
相關文章
相關標籤/搜索