3
还有一个方案:nginx配置来实现,未研究:https://github.com/ant-design/ant-design-pro/issues/1365#issuecomment-384496088

解决了什么问题?

spa项目新上线后,登陆有效期内用户,可以马上使用新上线资源。

原理:

  • 问:为什么新上线后,不能马上访问到新上线资源?
    答:因为设置了浏览器缓存;如果不刷新,访问的还是缓存的静态文件。
  • 问:刷新浏览器之后,就可以使用新上线资源,那在 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. 用户无感知

此技术方案实现的代价:

  1. 每次切换路由,都要进行一次打包字符串的判断,增加代码及请求

vue 项目代码修改的地方:

1、相应目录下,新建文件:static/json/build_str.json
2、build/build.js 修改:

// 将当前时间戳写入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()
})

3、src/main.js 修改:

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()
})
项目demo:
Vue CLI 2.x版本:https://github.com/cag2050/vue_cli_2.x_webpack_3_upgrade_4
Vue CLI 高版本:https://github.com/cag2050/spa_deploy_refresh

cag2050
519 声望18 粉丝

软件开发