前言
你是否也曾遇到过这种情况,每次发完版之后都还会有用户反馈问题没有被修复,一顿排查之后发现他用的还是旧的版本。
用户:在 XX 页面 XX 字段还是不展示
我:刷新下页面
用户:刷新了啊
我:强刷一下,Ctrl + F5
这一切都要归咎于 浏览器缓存,那么如何解决这一痛点呢?这篇文章将介绍如何检测版本变更并通知用户刷新页面。
实现思路
- 在项目构建(build)的时候,生成一个
version.json
版本信息文件,路径:dist/version.json
- 在切换路由的时候去请求服务器的
version.json
文件与本地缓存的版本信息做一个对比
准备工作
本文使用的是 Angular
技术栈,但是本质上还是使用的 webpack
去构建,所以万变不离其宗!
- angular | v17
- @angular-builders/custom-webpack | v17
开始
一、Angular 自定义 Webpack 配置
1.1 安装 @angular-builders/custom-webpack
npm install @angular-builders/custom-webpack -D
1.2 使用自定义配置运行开发服务器:@angular-devkit/build-angular -> @angular-builders/custom-webpack
"architect": {
...
"build": {
"builder": "@angular-builders/custom-webpack:browser",
"options": {
"customWebpackConfig": {
"path": "./extra-webpack.config.ts"
},
...
}
},
"serve": {
"builder": "@angular-builders/custom-webpack:dev-server",
"options": {
"browserTarget": "my-project:build"
}
}
...
}
1.3 配置 extra-webpack.config.ts
import * as webpack from "webpack";
export default (config: webpack.Configuration) => {
config.plugins = [
...config.plugins,
// 这里配置插件
];
return config;
};
二、自定义版本信息插件
2.1 创建插件 version-plugin.js
,参考文档 creating-a-plugin
const fs = require("fs");
const path = require("path");
class VersionPlugin {
constructor({ version }) {
this.version = version;
}
apply(compiler) {
compiler.hooks.done.tap("VersionPlugin", (stats) => {
const versionInfo = {
version: this.version,
buildTime: new Date().toISOString(),
};
const outputPath = stats.compilation.options.output.path;
const versionFilePath = path.resolve(outputPath, "version.json");
fs.writeFileSync(versionFilePath, JSON.stringify(versionInfo, null, 2));
console.log("Version file generated successfully!");
});
}
}
module.exports = VersionPlugin;
2.2 在 extra-webpack.config.ts
中使用 VersionPlugin
插件
import * as webpack from "webpack";
import * as VersionPlugin from "./version-plugin.js";
export default (config: webpack.Configuration) => {
const version = new Date().getTime();
config.plugins = [
...config.plugins,
// 将版本号写入全局变量
new webpack.DefinePlugin({
"process.env.VERSION": JSON.stringify(version),
}),
// 创建 version.json 放入 dist 目录
new VersionPlugin({ version: version }),
];
return config;
};
运行
npm run build
检测version.json
文件是否写入成功!
三、检测变更并通知
我这里选择的是在用户切换路由的时候去检测,当然也可以选择其它的时机,例如开一个定时器,等。
3.1 在 app.component.ts
中去监听路由变化
import { Router, NavigationStart } from "@angular/router";
export class AppComponent {
constructor(private router: Router) {
this.onRouterChange();
}
onRouterChange(): void {
this.router.events.subscribe((event) => {
if (event instanceof NavigationStart) {
this.checkVersion();
}
});
}
}
3.2 实现检测版本的方法,请求远程服务器的 version.json
版本信息与项目中的全局变量 process.env.VERSION
做对比
checkVersion(): void {
if (!environment.production) {
return;
}
fetch('./version.json')
.then(response => response.json())
.then(versionInfo => {
if (versionInfo.version !== process.env.VERSION) {
// TODO: 弹窗提示 或 直接刷新
this.refresh();
}
})
.catch(error => {
console.error(error);
});
}
refresh(): void {
window.location.reload(true);
}
done!
结语
看到这里,希望能够给你提供一点思路,方法有很多种,也欢迎一起交流讨论!