场景
探索提供一个直观且用户友好的前端检测版本更新的方式!既不会过分打扰用户,又能确保用户及时了解到新版本的可用性并选择是否进行更新。
落实
- node版本:20.11.0
- vue版本:3.4.34
- vite版本:5.3.5
- 自定义脚本vite-version-plugin.js
import fs from 'fs'
import path from 'path'
export default ({ version }) => {
let config = { publicDir: '' }
return {
name: 'version-plugin', // 必须的,将会在 warning 和 error 中显示
configResolved (resolvedConfig) {
// 存储最终解析的配置
config = resolvedConfig
}, buildStart () {
// 生成版本信息文件路径
// 编译时间作为版本信息
const content = JSON.stringify({ version })
writeVersion(config.publicDir + path.sep + 'version.json', content)
}
}
};
/**
* 写入文件
* @param fileName
* @param version
*/
function writeVersion (fileName, version) {
fs.writeFile(fileName, version, (err) => {
if (err) throw err
})
}
- vite.config.js调整
import dayjs from 'dayjs'
import versionPlugin from './vite-version-plugin.js'
dayjs.extend(advancedFormat)
const buildTime = dayjs().format('x') + ''
export default defineConfig({
define: {
__APP_VERSION__: JSON.stringify(buildTime)
},
plugins: [
versionPlugin({
version: buildTime
})
],
})
- 在App.vue中调整
import axios from 'axios'
let count = 0
const updateVersion = () => {
if (import.meta.env.MODE === 'production') {
document.addEventListener('visibilitychange', async () => {
if (document.visibilityState !== 'hidden') {
const res = await axios.get('version.json')
if (__APP_VERSION__ !== res.data.version) {
if(count === 0) {
count = 1
ElMessageBox.confirm('发现新版本, 是否更新?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
// 处理逻辑
async () => {
count = 0
window.location.reload(true)
}
}).catch(() => {
// 处理逻辑
async () =>{
count = 0
}
})
}
}
}
})
}
}
onMounted(() => {
updateVersion()
})
回顾
- 通过监听visibilitychange事件,发送版本请求version.json请求获取发布版本信息做对比,存在差异则更新;比对时机还需要进一步优化。
- 暂时没有添加频率规则,控制版本信息比对。