前言
你是否也曾遇到过这种情况,每次发完版之后都还会有用户反馈问题没有被修复,一顿排查之后发现他用的还是旧的版本。
用户:在 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!
结语
看到这里,希望能够给你提供一点思路,方法有很多种,也欢迎一起交流讨论!