解决SPA应用更新后,需要手动刷新才能获取到修改的页面内容

328 阅读2分钟

解决SPA应用更新后,需要手动刷新才能获取到修改的页面内容

Snipaste_2023-05-30_17-30-51.png

解决思路

​ 主要思路是在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();
  ...
});