Vue3 + Vite 生产环境缓存更新问题及自动检测方案详解
💡 一、问题背景
在使用 Vue3 + Vite + TypeScript + Ant Design Vue 搭建的前端项目中,
当我们部署新版本后,用户往往仍加载了旧版本的 JS/CSS 缓存。
这会导致:
✅ 页面没有更新
⚠️ 新功能或样式未生效
❌ 新接口调用报错、白屏
用户必须手动刷新或清除缓存才能加载最新版本,体验非常不好。
🎯 二、目标
我们希望实现一个自动检测更新机制:
✅ 定期检测是否有新版本
✅ 检测到后自动提示或刷新
✅ 纯前端实现,无需后端改动
✅ 构建时自动生成版本文件(如
meta.json
)
🧠 三、实现思路
核心逻辑非常简单:
构建时生成一个包含版本号的文件(
meta.json
)。
前端定时请求该文件,比较新旧版本号。
如果不一致,说明有新版本,提示刷新或自动刷新。
🛠️ 四、具体实现步骤
1️⃣ 构建时自动生成版本文件
在 vite.config.ts
中添加一个简单的自定义插件:
// vite.config.ts
import { writeFileSync } from 'fs'export default {plugins: [{name: 'generate-meta',closeBundle() {const version = new Date().toISOString()writeFileSync('dist/meta.json', JSON.stringify({ version }), 'utf-8')console.log(`✅ meta.json 生成成功: ${version}`)},},],
}
每次执行
vite build
后,dist/
目录下都会生成一个meta.json
文件:
{"version": "2025-10-21T05:03:14.123Z"
}
2️⃣ 编写版本检测工具
创建文件:src/utils/checkVersion.ts
// src/utils/checkVersion.ts// 初始化版本号(第一次访问时写入)
export async function initVersion() {try {const res = await fetch(`/meta.json?_t=${Date.now()}`)const data = await res.json()const version = data.versionlocalStorage.setItem('app-version', version)console.info('[初始化] 当前版本号:', version)} catch (e) {console.error('初始化版本信息失败:', e)}
}// 定期检测版本号是否变化
export function startVersionWatcher(interval = 60 * 1000) {setInterval(async () => {try {const res = await fetch(`/meta.json?_t=${Date.now()}`)const data = await res.json()const newVersion = data.versionconst oldVersion = localStorage.getItem('app-version')// 🧠 首次访问:写入初始版本if (!oldVersion) {localStorage.setItem('app-version', newVersion)console.info('[版本检测] 初始化版本号:', newVersion)return}// 检测到版本更新if (oldVersion !== newVersion) {console.warn('[版本检测] 检测到新版本,准备刷新页面')localStorage.setItem('app-version', newVersion)window.location.reload(true)}} catch (e) {console.error('版本检测失败:', e)}}, interval)
}
3️⃣ 在入口文件中启用检测
在 main.ts
中引入并启动:
import { initVersion, startVersionWatcher } from '@/utils/checkVersion'initVersion() // 初始化版本号
startVersionWatcher(60 * 1000) // 每 1 分钟检测一次
⚙️ 五、优化建议
项目 | 建议值 | 说明 |
---|---|---|
检测频率 | 1~3 分钟 | 频率太长更新不及时,太短浪费请求 |
请求参数 | ?_t=${Date.now()} | 防止 meta.json 被缓存 |
页面状态 | 可用 document.hidden | 页面非活跃时可跳过检测 |
提示方式 | Modal.confirm (Ant Design Vue) | 可提示用户确认刷新 |
示例弹窗提示:
import { Modal } from 'ant-design-vue'Modal.confirm({title: '检测到新版本',content: '系统有更新,是否立即刷新?',okText: '刷新',cancelText: '稍后',onOk: () => window.location.reload()
})
🔔 六、方案效果
✅ 第一次访问自动记录版本号
✅ 新版本发布后自动检测变化
✅ 自动刷新或提示刷新
✅ 用户无需手动清缓存
效果图示意:
前端定期检测 meta.json → 发现新版本 → 弹窗提示 → 用户刷新 → 页面加载最新代码
🧩 七、常见问题
① 第一次访问没有旧版本怎么办?
改进后已自动写入当前版本号,不再遗漏。
② meta.json
会被缓存吗?
不会。因为请求中携带了时间戳参数 _t=${Date.now()}
。
③ 可以改成用户确认刷新吗?
可以。用 AntD 的 Modal.confirm
替代 window.location.reload(true)
即可。
✍️ 八、Git 提交规范
这类修改属于构建与工具优化,推荐使用 chore
类型:
chore(cache): add version.json check to detect new build
类型 | 说明 |
---|---|
feat | 新功能 |
fix | 修复 bug |
chore | 构建/工具相关改动 |
refactor | 重构代码 |
🎉 九、总结
通过这一方案,我们实现了一个纯前端、自动检测并刷新版本的机制:
✅ 无需后端改动
✅ 防止旧版本缓存
✅ 自动刷新或提示用户更新
✅ 打包时自动生成版本文件