Skip to content
On this page

App 检查最新版本

为什么要检查更新

下述情况下,一旦服务器有新版本,客户端必须立即强制刷新页面:

  • 假如客户机理论上从不主动刷新页面,比如某些触摸屏设备,这样,除非专门重启设备或浏览器,否则页面不会刷新,这导致无法更新新版本,需要有一个刷新方案。

  • 假如前端已修复了严重 bug,急切需要客户机立即刷新 Web-App 页面。

那么如何刷新 Web-App 就是个问题,本文给出一个解决方案。

部署方案

1. vue.config.js 添加代码

代码有 2 个作用:

  • index.html传递htmlWebpackPlugin.options.version,这相当于本地版本号。

  • dist根目录生成manifest.json,这相当于线上版本号,只需轮询这个文件,对比本地版本号和线上版本号,就可以判断线上是否有新版本。

js
const fs = require('fs-extra');
const packageJson = require('./package.json');

class ManifestJsonWebpackPlugin {
  constructor() {}
  apply(compiler) {
    fs.writeJSONSync('./public/manifest.json', {
      version: packageJson.version,
    });
  }
}

module.exports = {
  chainWebpack(config) {
    config.when(process.env.NODE_ENV !== 'development', (config) => {
      config.plugin('html').tap((args) => {
        args[0].version = packageJson.version;
        return args;
      });
      config.plugin('ManifestJson').use(ManifestJsonWebpackPlugin);
    });
  },
};

2. index.html 添加代码

index.html<head></head>中添加代码,以便接收变量:

html
<meta name="version" content="<%= htmlWebpackPlugin.options.version %>" />

3. App.vue 添加代码

App.vuecreated周期函数准备一个setInterval,每隔 5 分钟 GET 一次/manifest.json。伪代码如下:

js
if (process.env.NODE_ENV === 'production') {
  const oldVersion = document.querySelector('meta[name=version]').getAttribute('content');
  setInterval(() => {
    ajax.get('/manifest.json').then((response) => {
      if (response.version !== oldVersion) {
        // 在网页顶部显示警告条:网站有新版本,60 秒后自动重启网站,请尽快保存当前工作
      }
    });
  }, 300000);
}

4. 准备警告条组件

正如上面的注释所说,前端准备一个不可关闭的警告条组件,警告条中的60 秒会自动倒计时,倒计时终了就location.reload()

使用方式

当需要强制刷新前端时,先提升package.json的版本号,再打包即可。

如果团队有经常更新版本号的制度,则可以进行以下约定:

  1. 修改if (response.version !== oldVersion),只当判断出大版本号有更新,才强制前端更新,小版本号更新则不触发强制更新。

  2. 不需前端强制更新的前提下,绝对不要提升大版本号。

杨亮的前端解决方案