项目背景
比如:项目新增了一些功能、或者修复某些bug,特别是修复bug,我们肯定希望当前正在访问的用户,可以立刻刷新页面。这样就可以偷偷的隐藏掉(只要bug不被发现,我就没错)。哈哈,言归正传,下面开始说解决方案。
我的思路
- 我们项目初始化一个配置文件(项目和版本信息)。
- 每次构建打包(
npm run build/yarn build)的时候,读取配置文件,得到版本信息,然后增加版本号,生成新的配置文件(fs),保存到dist目录。 再把更新后的版本号信息,重新写入我们的原始配置文件。 - 定义一个函数,
轮询请求这个dist文件夹下的配置文件(仅仅在生产环境),获取版本信息,首先保存版本信息到一个局部变量,后续每次请求,拿到的版本信息和该变量比较,不相等,则提示用户,有新版,给确认框确认?是否更新,是的话则调用location.reload。
这里说下版本号,我是比较简单的实现(就是递增一个原始ID,初始化为0)。
version首次从0开发,后续每次生成配置文件时,去递增(++version),这样就可以保证版本号唯一。
项目根目录创建project.json
{
"name":"project-name",
"version":0
}
生成新配置文件和更新原始配置文件
let { version, name } = require('./project.json')
const path = require('path')
const fs = require('fs')
const content = `{
"name":"${name}",
"version":${++version}
}`
fs.writeFile(path.resolve(__dirname, 'dist/version.json'), content, {}, (err) => {
if (!err) {
console.log('配置文件已经写入成功--->当前版本', version)
fs.writeFile(path.resolve(__dirname, 'project.json'), content, {}, (error) => {
if (!error) {
console.log('已经更新原始配置文件--->当前版本', version)
}
})
}
})
记得要去更新package.json文件的构建命令。
这里用webpack示例说明
"scripts": {
"build": "webpack --mode=production --config webpack.prod.js && node generateVersionJson.js"
},
算了,vite的也写下吧
"scripts": {
"build": "run-p type-check build-only && node generateVersionJson.js",
},
更新版本的请求函数
import axios from 'axios'
import { ElMessageBox, ElMessage } from 'element-plus'
let isFirstLoad = true
let currentVersion
const managementVersion = () => {
axios('/manual-project/dist/version.json', {
headers: {
'Cache-Control': 'no-cache',
}
}).then(res => {
const { version } = res.data
if (isFirstLoad) {
isFirstLoad = false
currentVersion = version
} else {
if (currentVersion !== version) {
ElMessageBox.confirm('发现新版本,是否更新?',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: '更新版本确认框?',
}
).then(() => {
ElMessage({
type: 'success',
message: '更新新版本了!!!',
onClose() {
location.reload()
}
})
}).catch(() => {
ElMessage({
type: 'info',
message: '你取消了版本更新',
})
})
}
}
})
}
if (process.env.NODE_ENV === 'production') {
setInterval(() => {
managementVersion()
}, 1000 * 60 * 30)
}
这里侧重说下axios,因为我们默认请求version.json文件,浏览器针对这种不变的文件会做优化,把它在磁盘缓存起来(disk cache),所以我们请求文件的时候,默认情况下,它会一直读取缓存,导致我们更新失败,所以要设置下请求头(header)axios('url',{headers: {'Cache-Control': 'no-cache'}}),这样再去请求,每次都会请求服务器,而不是缓存了。
总结
看下来发现其实还是比较简单的,就是请求那里要设置下(这里有点坑),我代码调试,看它一直请求(dist cache),费了点时间,其他的都是有思路就行了。
如果大家自己测试下的话,可以按以下步骤来:
git clone https://github.com/lzh-kf/manual-project.gitgit checkout masternpm i- 然后修改
src/login/index.vue的代码,再去修改下src/updateVersion.js,把轮询改成1000 * 1 * 1 - 本地预览,
cmd中执行:npm run preview,成功会在本地chrome浏览器打开项目。 - 再次修改
src/login/index.vue的代码,然后执行npm run build,等它构建完成,你就可以看到步骤5打开的网页会有提示框,提醒你更新,至此完成。