思路:
- 发布前端项目时,使用webpack构建命令生成一个json文件,json中写个随机生成的一个字符串(比如时间戳),每次打包程序都会自动更新这个json文件。
- 在项目中,通过定时任务或者在切换页面路由时,请求json文件。使用本地保存的上一次生成的字符串和json文件中的字符串进行比较,如果两个字符串不一样,则说明前端重新部署了,提醒用户进行更新或进行强制刷新的操作。
实现
1. version.js
项目根目录下新建version.js
const fs = require('fs') // 引入文件模块
const Timestamp = new Date().getTime()
fs.writeFile('public/version.json', '{"version":' + Timestamp + '}\n', function(err) {
if (err) {
return console.log(err)
}
})
2. package.json
修改构建命令,添加执行version.js的命令
"scripts": {
"build": "node version.js && vue-cli-service build"
}
3. vue.config.js
添加配置,自定义html注入变量
chainWebpack(config) {
// 获取版本号数据
const bpmVersion = require('./public/version.json')
// 自定义html注入变量
config.plugin('html').tap((args) => {
args[0].version = bpmVersion.version
return args
})
}
4. index.html
利用meta标签,存储版本号字段
<meta name="version" content="<%= htmlWebpackPlugin.options.bpmVersion %>" />
5. store.js
利用meta标签,存储版本号字段
const actions = {
checkVersion({ commit, state }) {
return new Promise(resolve => {
axios.get('/version.json?v=' + new Date().getTime(),
{ headers: { 'Cache-Control': 'no-cache' },
baseURL: window.location.origin })
// 请求json文件的内容, 并且禁止缓存
.then(res => {
const latestVersion = res.data.version
const currentPageVersion = Number(document.querySelector('meta[name="version"]').content || '')
resolve(latestVersion === currentPageVersion)
}).catch(err => {
console.log('checkVersion err', err)
})
})
}
}
6. router.js
切换页面路由,比对版本
router.afterEach(async() => {
if (process.env.NODE_ENV == 'production') {
const checkVersion = await store.dispatch('settings/checkVersion')
if (!checkVersion) { // 获取的版本号不等时
// 1、强制刷新
Message.warning('正在自动升级新版本...', 2, () => {
window.location.reload() // 版本不同 刷新 获取最新版本
})
// 2、需要用户主动刷新,需要考虑只提醒一次,而不是每次切换路由都提示
//MessageBox.alert('检测到新版本,刷新后立即使用', '发现新版本', {
// confirmButtonText: '立即刷新',
// showClose: false,
// callback: action => {
// window.location.reload() // 版本不同 刷新 获取最新版本
// }
//})
}
}
})