问题描述:
在开发的过程中经常会遇到页面更新发版后,用户访问的页面还是缓存中的页面,即使打包的文件名使用了内容哈希(根据文件内容生成哈希,并将其合并到文件名中(比如 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 配置的脚本指令:
④ 最后执行提交可以看到会自动修改版本并提交文件:
总结:到这里我们每次提交代码都能自动更新版本号了,用户访问页面前会检测是否有新版本发布,有则强制加载新页面(这里检测新版本的功能可以根据项目需求在不同时机调用,比如轮询、进入页面后...再检测版本)。