前端单文件入口发布新版本 缓存问题
在现代 javascript
框架项目开发中,一直有一个令人都疼的问题,就是缓存问题;每次发版完之后由于浏览器缓存机制,用户端不会实时获取新的项目页面,甚至有可能出现静态文件获取报404。
方法思路
- 在入口文件中配置文件更新后 缓存同步更新
- 打包的时候 生成一个唯一的版本号,并添加到
入口目录/config.json
- 每次
路由
发生变更的时候,判断版本号是否发生变化,如果发生变化,则刷新当前文件
以 vue
项目为例
- 在项目
public
文件夹下的index.html
入口文件中添加如下代码
1<meta http-equiv="pragma" content="no-cache">
2<meta http-equiv="cache-control" content="no-cache, no-store, must-revalidate">
3<meta http-equiv="expires" content="0">
- 生成版本号 在vue.config.js中添加如下配置
1const Timestamp = (new Date()).getTime()
2const gitRevisionPlugin = new GitRevisionPlugin() // 依赖 git-revision-webpack-plugin
3const VERSION = `${gitRevisionPlugin.branch()}_${gitRevisionPlugin.version()}_${gitRevisionPlugin.commithash()}_${Timestamp}` // git分支 时间戳;这里可以根据自己喜欢的方式加上随机版本号
4process.env.VUE_APP_VERSION = VERSION // 记录到env,并在vuex中记录,用于后面版本号对比校验
5
6const configJSON = require(resolve('public/config.json')) // public文件夹下新建config.json
7const configFile = path.resolve(__dirname, 'public/config.json')
8fs.writeFileSync(configFile, JSON.stringify({
9 ...configJSON,
10 version: VERSION
11}, null, 2))
- 在utils下,新建systemUpdate.js
1import axios from 'axios'
2import store from '@/store'
3import { removeLocalStorage, setLocalStorage } from '@/utils/localStorage'
4import { MessageBox } from '@/element-ui'
5
6const getConfig = () => {
7 return new Promise((resolve) => {
8 axios.get(`${process.env.VUE_APP_DOMAIN}/config.json`, {
9 params: {
10 _t: (new Date()).getTime()
11 }
12 }).then(res => {
13 resolve(res.data)
14 })
15 })
16}
17
18export async function isNewVersion () {
19 if (process.env.NODE_ENV === 'development') {
20 return false
21 }
22 const config = await getConfig()
23 let newVersion = config.version
24 let oldVersion = store.getters.version
25 let isUpdated = oldVersion !== newVersion
26 if (isUpdated) { // 如果version不一致,则清除本地基础数据
27 removeLocalStorage('AREADATA')
28 MessageBox.alert(
29 '系统检测到有新版本,请刷新页面!',
30 '系统提示',
31 {
32 showClose: false,
33 confirmButtonText: '刷新页面'
34 }
35 ).then(() => {
36 setLocalStorage('VERSION', { version: newVersion })
37 window.location.reload()
38 }).catch(() => {
39 })
40 }
41 return isUpdated
42}
- 判定版本号
1router.beforeEach(async (to, from, next) => {
2 // 判断版本号,如果不一致则提示用户刷新页面
3 const isUpdate = await isNewVersion()
4 if (isUpdate) return false
5...