【Vue】生产环境部署后提示触发客户端更新(提醒客户是否需要更新资源),自动化更改版本

742 阅读1分钟

方案一:监听error事件

1.给打包生成的文件加上hash值
vue cli2修改vue项目根目录下的 build/webpack.prod.conf.js文件,vue cli3会自动添加hash值

const timeStamp = new Date().getTime();
module.exports = {
    publicPath:"/",
    configureWebpack: { // webpack 配置
    output: {
      // 把应用打包成umd库格式
      library:'myLibrary',
      // 输出重构  打包编译后的文件名称  【模块名称.时间戳】
      filename: `[name].${timeStamp}.js`,
      libraryTarget:'umd',
      globalObject:'this',
    },
  },
}

2.监听error事件,如果资源报错,强制页面刷新

window.addEventListener('error', handleListenerError, true);

function handleListenerError (eventErr){

  if (eventErr.srcElement.localName == 'link' || eventErr.srcElement.localName == 'script') {
        alert('因版本更新,页面需重新载入,请核对当次操作数据');
        window.location.reload();

  }
  eventErr.preventDefault()

}

方案二:判断本地与服务端version是否变更(推荐)

1.public目录下新增version.json文件 ,轮询向浏览器发get请求该文件中的version与当前packjson中的version做对比,不一样时则执行刷新逻辑

{
    "version": "1.0.0",
    "must": true
}

在公共文件里加逻辑,我加到了layout.vue中,具体根据项目而定。

import axios from 'axios'
axios.defaults.headers['Cache-Control'] = 'no-cache'
const versionData = require('../../package.json')
mounted(){
 setInterval(() => {
      this.checkVersion()
    }, 3000)
},
methods:{
 checkVersion() {
      const { version } = versionData
      axios.get(`${window.location.origin}/version.json?${Date.now()}`).then(res => {
        const { version: newVersion, must } = res.data
        if (version !== newVersion && must) {
           alert('检测到系统有变更,系统将在5秒后强制刷新')
            setTimeout(() => {
                    window.location.reload();
            }, 5000);
        }
      })
    },
}

高阶(基于方案二 自动化递增版本,不需要手动更改版本号)

1.新建version.js

//引入nodejs fs模块 
const fs = require("fs");
const packageJson = require("./package.json");
const publicVersion = require("./public/version.json");
// 获取当前package.json中的版本号,递增
const getVersion = () => {
  const res = packageJson.version;
  const arr = res.split(".");
  if (arr[2] < 99) {
    if (arr[2] < 9) {
      arr[2] = "0" + (+arr[2] + 1);
    } else {
      arr[2] = +arr[2] + 1;
    }
  } else if (arr[1] < 9) {
    arr[1] = +arr[1] + 1;
    arr[2] = 0;
  } else {
    arr[0] = +arr[0] + 1;
    arr[1] = 0;
    arr[2] = 0;
  }
  return arr.join(".");
};
//将版本号写入 publick.json和version.json中
const newVersion = getVersion();
packageJson.version = newVersion;
publicVersion.version = newVersion;
//此处特别注意:JSON.stringify的第二个参数如加了数组则只格式化数组中的字段,
//此处加null为了保留原有packjson的格式,第三个参数为缩进的空格树
fs.writeFileSync("./package.json", JSON.stringify(packageJson, null, 2));
fs.writeFileSync("./public/version.json", JSON.stringify(publicVersion, null, 2));

2.修改packjson启动命令

 "scripts": {
    "dev": "vue-cli-service serve",
    "build:prod": "vue-cli-service build",
    "build:prod:version": "node version.js && vue-cli-service build",
  },

正常打包不需要版本提示时可用npm run build:prod
需要版本更新强制提醒时npm run build:prod:version