解决SPA应用更新后,需要手动刷新才能获取到修改的页面内容
解决思路
主要思路是在public文件夹下添加version.josn文件,每次打包时修改version.json文件中的版本号。然后在路由的全局后置钩子函数(afterEach)中通过axios访问服务器中的version.json文件,对比localStorage中的版本号和服务器中version.json文件的版本号,如果不相等就主动刷新浏览器获取最新版本。
具体实现
1.webpackPlugin
封装一个webpack插件,主要作用就是在打包时如果public文件夹下不存在version.json文件就自动创建,存在则自动修改version.json文件中的版本号(防止打包后忘记更改版本号)。在根目录创建editVersionPlugin.js文件:
const fs = require("fs");
module.exports = class editVersionPlugin {
constructor(filePath) {
this.filePath = filePath;
// console.log("options", options);
}
apply(compiler) {
compiler.hooks.run.tapAsync(
"editVersionPlugin",
(compilation, callback) => {
writeFileContent(this.filePath);
callback();
}
);
}
};
function writeFileContent(filePath) {
// 检测version.json文件是否存在
if (fs.existsSync(filePath)) {
// 读取/public/version.json文件中的内容;
fs.readFile(filePath, "utf-8", (err, data) => {
if (err) throw err;
let newVersion = JSON.parse(data);
// 将当前version的值改为当前时间戳
newVersion.version = new Date().getTime();
console.log(newVersion.version);
// 重写该文件
fs.writeFile(filePath, JSON.stringify(newVersion), "utf8", (err) => {
if (err) throw err;
console.log("success done");
});
});
} else {
let newVersion = {
version: new Date().getTime(),
};
// 创建文件并写入
fs.writeFile(filePath, JSON.stringify(newVersion), "utf8", (err) => {
if (err) throw err;
console.log("success done");
});
}
}
在vue.config.js文件中引入并添加该插件:
const editVersionPlugin = require("./editVersionPlugin");
module.exports = {
...
configureWebpack: {
name: name,
resolve: {
alias: {
"@": resolve("src"),
},
},
plugins: [new editVersionPlugin(resolve("public/version.json"))],
}
....
}
2.version.js
在utils文件夹下创建version.js文件,该文件主要用于向服务器访问项目版本号,比对本地项目版本号与服务器上的版本号。
import axios from "axios";
export async function isNewVersion() {
// 访问路径
const url = `//${window.location.host}/${process.env.VUE_APP_DIR}/version.json`;
const res = await axios.get(url);
const version = res.data.version;
// 从localStorage中获取version
const localVersion = localStorage.getItem("version");
if (localVersion && localVersion != version) {
localStorage.setItem("version", version);
// 刷新浏览器
window.location.reload();
} else {
localStorage.setItem("version", version);
}
}
3.permission.js
最后在根目录中的permission.js文件中引入isNewVersion(),并在afterEach()中调用该函数。
import { isNewVersion } from "@/utils/version";
router.afterEach(() => {
isNewVersion();
...
});