基于Vue的项目更新发版时,用户如何无感刷新页面加载最新资源

·
2025-10-15 05:56:58

问题描述:

在开发的过程中经常会遇到页面更新发版后,用户访问的页面还是缓存中的页面,即使打包的文件名使用了内容哈希(根据文件内容生成哈希,并将其合并到文件名中(比如 app.abcd123.css),这提供了一种识别更改的可靠方法。即使对文件进行微小的更改也会产生新的哈希值,并随后产生新的文件名),如果用户不手动刷新页面,访问的依然是旧的资源文件,特别是5+App应用,不像浏览器有刷新按钮,App每次都要手动清除缓存再进入应用才能访问最新应用。

解决思路:

1. 用户访问页面时检测当前版本与服务器版本是否一致,若不一致,可以强制浏览器从服务器重新加载页面

2. 每次提交项目时能自动更新修改版本号

解决方法:

1. 存储版本信息

在static目录下添加一个 version.json 文件来存储版本信息:

{

"version": "1.0.2",

"oldVersion": "1.0.1"

}

2. 比较当前版本与服务器版本

添加一个工具函数 versionUpdate.js 用于比较服务器 version.json 和当前 package.json 文件中的版本号字段是否一致:

注意:1)这里version.json要加上时间戳参数,保证请求到的是服务器最新的版本号

2) window.location.reload(true)一定要传true参数,强制浏览器从服务器重新加载页面

import axios from 'axios'

import packageApp from "../../package.json"

const appVersion = packageApp.version

const isNewVersion = () => {

let url = `./static/version.json?t=`+new Date().getTime();

axios.get(url).then(res => {

let version = res.data.version;

if (appVersion != version) {

console.log("刷新")

window.location.reload(true);

return true;

}else {

return false

}

});

};

export default {

isNewVersion

}

3. 进入页面前检测版本

路由文件 router.js 添加钩子函数:在路由导航之前判断是否有新版本发布,是则不进入页面,否则继续访问页面

import versionTood from '@/utils/versionUpdate'

router.beforeEach((to, from, next) => {

next();

versionTood.isNewVersion()

})

4. 自动更新版本号

到这里,用户访问页面前会检测是否有新版本,有新版本会自动强制从服务器加载页面的功能已经实现了,接下来就差版本号的更新,每次手动更新版本号的话容易漏改出错,那么该如何在每次提交项目自动更新版本号呢?

1)在根目录下添加 generate-build-version.js 来自动往 version.json 和 package.json修改写入新的版本号:

const fs = require('fs')

// 从 package.json 读取当前版本

const packageJson = require('./package.json')

const appVersion = packageJson.version

// 更新版本的函数

const incrementVersion = version => {

const versionArray = version.split('.')

const [major, minor, patch] = versionArray

// 检查补丁版本是否为 9,然后增量更新次版本号

if (parseInt(patch) === 9) {

const newMinor = parseInt(minor) + 1

return `${major}.${newMinor}.0`

}

// 增量更新次版本号

const newPatch = parseInt(patch) + 1

return `${major}.${minor}.${newPatch}`

}

// 计算新版本号

const newVersion = incrementVersion(appVersion)

// 基于新版本号更新 package.json

packageJson.version = newVersion

fs.writeFileSync(

'./package.json',

JSON.stringify(packageJson, null, 2),

'utf-8'

)

// 基于新版本号创建 version.json

const metaJson = { version: newVersion, oldVersion: appVersion }

fs.writeFileSync(

'./static/version.json',

JSON.stringify(metaJson, null, 2),

'utf8'

)

console.log('Version has been updated in package.json and version.json:'+newVersion)

2)利用husky的pre-commit,在每次git commit 之前自动执行 generate-build-version.js 文件实现每次提交代码前自动更新版本号:

① 安装husky

npm install -D husky

② 执行 npx husky-init ,在根目录下生成 .husky 文件夹

npx husky-init

③ 在 .husky/pre-commit文件中加入脚本命令(执行git commit 时会先修改版本号并提交改动的文件)

#!/usr/bin/env sh

. "$(dirname -- "$0")/_/husky.sh"

npm run generate-build-version && git add package.json static/version.json

这里的 npm run generate-build-version 是对应 package.json里的scripts 配置的脚本指令:

④ 最后执行提交可以看到会自动修改版本并提交文件:

总结:到这里我们每次提交代码都能自动更新版本号了,用户访问页面前会检测是否有新版本发布,有则强制加载新页面(这里检测新版本的功能可以根据项目需求在不同时机调用,比如轮询、进入页面后...再检测版本)。