由于浏览器默认的缓存策略 导致每次版本更新后 用户如果不进行手动刷新看到的还是旧版本内容 影响用户体验 以下为这两天上网查阅资料后的解决方法 (记录)
思路:在每次打包生产代码时,根据请求服务器端的 version.json 中的版本号和浏览器本地缓存的版本号进行对比来监控版本迭代更新(注意: 要禁止浏览器缓存 index.html 和 version.json!!!)
location ~ .*\.(htm|html|json)?$ {
expires -1;
}
一、在src目录下的plugins文件夹下创建refreshPlugin.ts文件
import fs from "fs";
import path from "path";
type Version = {
version: number | string;
};
interface Config {
publicDir: string;
}
export default ({ version }: Version) => {
let config: Config = { publicDir: "" };
return {
name: "version-plugin",
configResolved(resolvedConfig: Config) {
config = resolvedConfig;
},
buildStart() {
const file = config.publicDir + path.sep + "version.json";
const content = JSON.stringify({ version });
writeVersion(file, content);
},
};
};
function writeVersion(
fileName: string,
version: string | NodeJS.ArrayBufferView
) {
fs.writeFile(fileName, version, (err) => {
if (err) throw err;
});
}
二、在vite.config.ts中引入插件,并define__APP_VERSION__,这样在打包的时候__APP_VERSION__和version.json中的值是保持一致.
import versionPlugin from "./src/plugins/refreshPlugin";
const timeVersion = new Date().getTime();
export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
return {
plugins: [
versionPlugin({
version: timeVersion,
}),
],
define: {
__APP_VERSION__: JSON.stringify(timeVersion),
},
};
});
三、在utils文件夹下创建versionCheck.ts文件
import axios from "axios";
export const versionCheck = async () => {
if (import.meta.env.MODE === "development") return;
const res = await axios.get("version.json");
if (__APP_VERSION__ !== res.data.version) {
window.location.reload();
}
};
四、检测版本更新的时机
1.路由切换时检测
router.afterEach(async () => { await versionCheck() })
2.监听 `visibilitychange` 事件
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "visible") versionCheck();
});
3. 资源加载错误时
window.addEventListener('error',(event) =>{
},true)