前端版本更新检查,实现页面自动刷新
使用
vite
对项目进行打包,对 js 和 css 文件使用了 chunkhash 进行了文件缓存控制,但是项目的
index.html
文件在版本频繁迭代更新时,会存在被浏览器缓存的情况。
在发版后,如果用户不强制刷新页面,浏览器会使用旧的
index.html
文件,在跳转页面时会向服务器端请求了上个版本 chunkhash 的 js 和 css 文件,但此时的文件已经在版本更新时已替换删除了,最终表现为页面卡顿,控制台报错 404。
解决思路
思路 1
服务器端发版时,上一个版本的
assets
内的文件不删除。
缺点是会随着频繁发版,服务器端前端项目文件会越来越多,浪费空间;若旧页面的接口涉及到参数改动等,会引起报错;流水线使用 docker 打包部署会变得非常麻烦。
思路 2
在每次打包生产代码时,在
public
下生成一个
version.json
版本信息文件,页面跳转时请求服务器端的
version.json
中的版本号和浏览器本地缓存的版本号进行对比,从而监控版本迭代更新,实现页面自动更新,获取新的
index.html
文件(前提是服务器端对
index.html
进行不缓存配置)。
- 首先应该禁止浏览器缓存
index.html
和version.json
,这里实现nginx
的不缓存处理添加nginx
配置location ~ .*\.(htm|html|json)?$ { expires -1;}
- 使用Vite 插件打包时自动生成版本信息版本信息插件
// versionUpdatePlugin.jsconst fs =require('fs')const path =require('path')constwriteVersion=(versionFile, content)=>{// 写入文件 fs.writeFile(versionFile, content,(err)=>{if(err)throw err })}exportdefault(options)=>{let config return{name:'version-update',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)})}},}}
vite 配置文件// vite.config.jsexportdefaultdefineConfig((config)=>{const now =newDate().getTime()return{...define:{// 定义全局变量__APP_VERSION__: now,},plugins:[...versionUpdatePlugin({version: now,}),],...}})
- 路由跳转时,实时检测版本检测到新版本自动刷新页面,应该使用前置守卫,在跳转失败报错前检测,跳转失败不会触发后置守卫
const router =useRouter()// 这里在路由全局前置守卫中检查版本router.beforeEach(async()=>{awaitversionCheck()})// 版本监控constversionCheck=async()=>{if(import.meta.env ==='development')returnconst response =await axios.get('version.json')// eslint-disable-next-line no-undefif(__APP_VERSION__ !== response.data.version){// eslint-disable-next-line no-undefElMessage({message:'发现新内容,自动更新中...',type:'success',showClose:true,duration:1500,onClose:()=>{ window.location.reload()},})}}
版权归原作者 Naomi_233 所有, 如有侵权,请联系我们删除。