在 Vue 项目中检测新版本发布的具体方案

Daotin 于 2024-10-11 发布 编辑

背景

每次测试反馈问题没改,检查了半天,才发现是缓存。。。

核心思路

  1. 在项目构建(build)的时候,生成一个 version.json 版本信息文件,路径:dist/version.json
  2. 在切换路由的时候去请求服务器的 version.json 文件与本地缓存的版本信息做一个对比

步骤

1. 在构建过程中生成 version.json 文件

在项目构建时,生成一个包含版本信息的 version.json 文件,可以使用 Webpack 插件或脚本实现。

创建自定义 Webpack 插件:

// build/version-plugin.js
const fs = require('fs');
const path = require('path');

class VersionPlugin {
  apply(compiler) {
    compiler.hooks.done.tap('VersionPlugin', () => {
      const version = Date.now(); // 使用时间戳作为版本号
      const content = JSON.stringify({ version });

      fs.writeFileSync(path.join(__dirname, '../dist/version.json'), content);
    });
  }
}

module.exports = VersionPlugin;

在 Webpack 配置中引入插件:

// vue.config.js
const VersionPlugin = require('./build/version-plugin');

module.exports = {
  // 其他配置
  configureWebpack: {
    plugins: [new VersionPlugin()],
  },
};

2. 在应用中检测版本变化

在应用启动或路由切换时,定期检查 version.json 文件,比较当前版本与服务器版本。

创建版本检测工具:

// src/utils/versionChecker.js
import axios from 'axios';

let currentVersion = null;

export function checkVersion() {
  // 为防止缓存影响,使用时间戳(或nginx禁用缓存)
  axios
    .get('/version.json', { params: { t: Date.now() } })
    .then((response) => {
      const newVersion = response.data.version;
      if (!currentVersion) {
        currentVersion = newVersion;
      } else if (currentVersion !== newVersion) {
        // 版本有更新,提示用户
        alert('检测到新版本,点击确定刷新页面。');
        window.location.reload();
      }
    })
    .catch((error) => {
      console.error('版本检测失败:', error);
    });
}

3. 在应用入口或路由守卫中调用版本检测

在应用入口文件中:

// src/main.js
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import { checkVersion } from './utils/versionChecker';

Vue.config.productionTip = false;

// 应用启动时检测版本
checkVersion();

new Vue({
  router,
  render: (h) => h(App),
}).$mount('#app');

在路由守卫中:

// src/router/index.js
import Vue from 'vue';
import Router from 'vue-router';
import { checkVersion } from '../utils/versionChecker';

Vue.use(Router);

const router = new Router({
  // 路由配置
});

router.beforeEach((to, from, next) => {
  checkVersion();
  next();
});

export default router;