前言
你是否也曾遇到過這種情況,每次發完版之后都還會有用戶反饋問題沒有被修復,一頓排查之后發現他用的還是舊的版本。
用戶:在 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!
結語
看到這里,希望能夠給你提供一點思路,方法有很多種,也歡迎一起交流討論!