Front-end version management

1. Scenario requirements

When users use our web project, because sometimes there will be an update of the production environment, if the user loads the webpage before the update, if the user does not refresh after the update, it will occasionally cause an error on the page. In this case, we often prompt the user to refresh That's fine, it's not a business or code-level error. Since this situation has happened many times recently, the boss asked me to solve it.

2. Solutions

Do version number management, and do a version verification every time the interface is called. If the verification passes, the interface will be accessed normally. If the verification fails, a special status code will be returned. The front end will automatically refresh the page to obtain the latest page static resources.

3. Realization

First of all, it is necessary to change the version number every time it is packaged, that is, to automatically change the version number. This is achieved by executing a piece of js when packaging

package.json

{
    "name": "project",
	"version": "0.0.11",
	"lastBuildTime": "2023-02-24 17:28:52",
	"scripts": {
		"dev": "vite",
		"start": "vite",
		"build": "vite build --mode=production",
		"build:auto": "node ./myBuild.js && vite build --mode=production",
		"build:stag": "vite build --mode=staging",
		"serve": "vite preview"
	}
}

myBuild.js


const fs = require("fs")
const dayjs = require("dayjs")
const axios = require("axios")
// 构建版本号的函数,这里只简单做下递增,后面可以优化成每构建一定次数的版本之后几句自动给二级版本号加1
const versionGenerrator = (version) => {
  let newVersion = Number(version[2]);
  console.log([version[0], version[1], ++newVersion].join("."));
  return [version[0], version[1], ++newVersion].join(".");
};
// 设置版本号--传入版本号并保存至数据库,本地也重新生成package.json的文件
const setVersion = (version) => {
  // 构造传入后端接口的参数
  let data = {
    id: 59,
    paramKey: "version_web",
    paramValue: version,
  };
  try {
    axios
      .post(
        "https://gateway.xxxxxxx.com/platform/config/updateByKey",
        data,
        {
          headers: {
            "Content-Type": "application/json; charset=UTF-8",
          },
        }
      )
      .then((response) => {
        if (response.data?.code == 200 && response.data?.data == 1) {
          console.log("文件版本号修改成功,开始写入本地文件");
          packageJson.version = version;
          packageJson.lastBuildTime = dayjs().format("YYYY-MM-DD HH:mm:ss");
          fs.writeFile(
            "./package.json",
            JSON.stringify(packageJson, null, "\t"),
            (err) => {
              if (err) {
                console.log("写入文件失败,请检查是否拥有文件夹权限", err);
              } else {
                console.log("文件写入成功-->" + packageJson.lastBuildTime);
              }
            }
          );
        }
      });
  } catch (error) {
    console.log("版本号写入接口失败,已停止");
  }
};
//  先读取package.json
let packageJson = JSON.parse(fs.readFileSync("./package.json"));
//  构建新的版本号
let version = versionGenerrator(packageJson.version.split("."));
// 调用接口设置到后端并且声成新的package.json
setVersion(version);

At this point, the version number has been automatically changed and submitted to the server. The next step is to verify the version number every time the interface is called. I choose to directly put the verification action on the gateway. When the verification fails It returns a 505 status code. What the front end needs to do is to put the current version number in the headers when calling the interface. This operation is placed on the axios request interceptor and response interceptor that we have packaged.

// 请求拦截
service.interceptors.request.use(
  (config) => {
    // JWT鉴权处理
    if (store.getters["user/token"]) {
      config.headers["Token"] = store.state.user.token;
    }
    config.headers["version_web"] = version; //版本号,从package.json中引入
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

// 响应拦截
service.interceptors.response.use(
  (response) => {
    if(response.code==505){
        ElMessage.error("检查到版本号不一致自动刷新页面");
        setTimeout(() => {
          window.location.reload();
        }, 3000);
    }
  }
);

This function is fully realized here. If the client browser loads the static file of version 0.0.1 and the version number in the database is 0.0.2, the call interface will return 505 and automatically reload the page. However, after discussing with our back-end architecture, he thought that this implementation method would cost too much to the back-end, and said that it is best to use the publish-subscribe model. I am not very clear about how to subscribe in this scenario, nor do I know the mainstream in the market. The solution is what I came up with and implemented it this way. If you have a small partner who understands, please be sure to private message me and ask for paid help.

Guess you like

Origin blog.csdn.net/qq_52965813/article/details/129206250