Vite+Vue3项目版本更新检查与页面自动刷新的实现方案

 更新时间:2025年09月18日 08:27:15   作者:NBtab  
使用 Vite 对 Vue 项目进行打包,对 js 和 css 文件使用了 chunkhash 进行了文件缓存控制,但是项目的 index.html 文件在版本频繁迭代更新时,会存在被浏览器缓存的情况,所以本文介绍了Vite+Vue3项目版本更新检查与页面自动刷新方案,需要的朋友可以参考下

问题

使用 Vite 对 Vue 项目进行打包,对 js 和 css 文件使用了 chunkhash 进行了文件缓存控制,但是项目的 index.html 文件在版本频繁迭代更新时,会存在被浏览器缓存的情况。

在发版后,如果用户不强制刷新页面,浏览器会使用旧的 index.html 文件,在跳转页面时会向服务器端请求了上个版本 chunkhash 的 js 和 css 文件,但此时的文件已经在版本更新时已替换删除了,最终表现为页面卡顿,控制台报错 404。

解决思路

在每次打包生产代码时,在 public 目录下生成一个 version.json 版本信息文件,页面跳转时请求服务器端的 version.json 中的版本号和浏览器本地缓存的版本号进行对比,从而监控版本迭代更新,实现页面自动更新,获取新的 index.html 文件(前提是服务器端对 index.htmlversion.json 不缓存)。

第一步:配置服务器,禁止关键文件缓存

要实现版本对比,需确保 index.html 和后续生成的版本文件 version.json 不被浏览器缓存 —— 每次请求均从服务器获取最新内容。以 Nginx 为例,添加如下配置:

location ~ .*\.(htm|html|json)?$ {
    expires -1;
}

第二步:开发 Vite 插件,自动生成版本信息

通过自定义 Vite 插件,在打包时自动在 public 目录下生成 version.json 文件,记录当前版本标识(建议用时间戳,确保每次打包版本号唯一)。 TypeScript 版本插件(src/plugins/versionUpdatePlugin.ts)

// versionUpdatePlugin.ts
import fs from "node:fs"
import path from "node:path"

import type { ResolvedConfig } from "vite"

function writeVersion(versionFile: string, content: string) {
  // 写入文件
  fs.writeFile(versionFile, content, (err) => {
    if (err) throw err
  })
}

export default (version: string | number) => {
  let config: ResolvedConfig
  return {
    name: "version-update",
    configResolved(resolvedConfig: ResolvedConfig) {
      // 存储最终解析的配置
      config = resolvedConfig
    },
    buildStart() {
      // 生成版本信息文件路径
      const file = config.publicDir + path.sep + "version.json"
      // 这里使用编译时间作为版本信息
      const content = JSON.stringify({ version })
      if (fs.existsSync(config.publicDir)) {
        writeVersion(file, content)
      } else {
        fs.mkdir(config.publicDir, (err) => {
          if (err) throw err
          writeVersion(file, content)
        })
      }
    },
  }
}

JavaScript 版本插件(src/plugins/versionUpdatePlugin.js)

// versionUpdatePlugin.js
const fs = require("fs")
const path = require("path")

const writeVersion = (versionFile, content) => {
  // 写入文件
  fs.writeFile(versionFile, content, (err) => {
    if (err) throw err
  })
}

export default (options) => {
  let config

  return {
    name: "version-update",
    configResolved(resolvedConfig) {
      // 存储最终解析的配置
      config = resolvedConfig
    },
    buildStart() {
      // 生成版本信息文件路径
      const file = config.publicDir + path.sep + "version.json"
      // 这里使用编译时间作为版本信息
      const content = JSON.stringify({ version: options.version })
      if (fs.existsSync(config.publicDir)) {
        writeVersion(file, content)
      } else {
        fs.mkdir(config.publicDir, (err) => {
          if (err) throw err
          writeVersion(file, content)
        })
      }
    },
  }
}

第三步:配置 Vite,注入全局版本变量

在 vite.config.js/ts 中引入上述插件,同时定义全局版本变量 __APP_VERSION__(供前端对比使用),建议用当前时间戳作为版本号,确保每次打包版本唯一。

类型声明(TS 项目必备)

若使用 TypeScript,需在 vite-env.d.ts 或 env.d.ts 中添加全局变量类型声明,避免类型报错:

// vite-env.d.ts
declare const __APP_VERSION__: string

// vite.config.js or vite.config.ts
export default defineConfig((config) => {
  const now = new Date().getTime()
  return {
    // ...
    define: {
      // 定义全局变量
      __APP_VERSION__: now,
    },
    plugins: [
      // ...
      versionUpdatePlugin({
        version: now,
      }),
    ],
    // ...
  }
})

第四步:前端实现版本检测,触发自动刷新

利用 Vue Router 的全局前置守卫,在每次页面跳转前检查版本 —— 对比浏览器端全局变量 __APP_VERSION__ 与服务器端 version.json 中的版本号,若不一致则提示用户并自动刷新页面(选择前置守卫是因为跳转失败不会触发后置守卫,可在报错前完成检测)。

const router = useRouter()
// 这里在路由全局前置守卫中检查版本
router.beforeEach(async () => {
  await versionCheck()
})

// 版本监控
const versionCheck = async () => {
  if (import.meta.env.MODE === "development") return
  const response = await axios.get("version.json")
  if (__APP_VERSION__ !== response.data.version) {
    ElMessage({
      message: "发现新内容,自动更新中...",
      type: "success",
      showClose: true,
      duration: 1500,
      onClose: () => {
        window.location.reload()
      },
    })
  }
}

最后

到此这篇关于Vite+Vue3项目版本更新检查与页面自动刷新的实现方案的文章就介绍到这了,更多相关Vite+Vue3项目版本更新检查与刷新内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue3中的useAttrs和props的区别解析

    vue3中的useAttrs和props的区别解析

    在vue3中, 提供了一个 useAttrs 的方法它接收到的参数一 prop中可以接收到的数据是基本一样的如果我们想自已写一个组件, 把 elementPlus 中的期中一个组件封装一下,这篇文章主要介绍了vue3中的useAttrs和props的区别,需要的朋友可以参考下
    2023-09-09
  • vue ssr 指南详读

    vue ssr 指南详读

    这篇文章主要介绍了vue ssr 指南详读,详细的介绍了什么是SSR以及如何使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • vue mounted 调用两次的完美解决办法

    vue mounted 调用两次的完美解决办法

    在开发中发现其中一个页面moutned调用了两次,而其他页面正常,表示很懵逼,然后查找原因,终于找到了,其实归根到底是要知道mounted的调用机制问题。这篇文章主要介绍了vue mounted 调用两次的解决办法,需要的朋友可以参考下
    2018-10-10
  • 15 分钟掌握vue-next函数式api(小结)

    15 分钟掌握vue-next函数式api(小结)

    这篇文章主要介绍了15 分钟掌握vue-next函数式api(小结),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-10-10
  • vue基础之详解ElementUI的表单

    vue基础之详解ElementUI的表单

    这篇文章主要为大家详细介绍了vue基础之ElementUI的表单,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02
  • vue Watch和Computed的使用总结

    vue Watch和Computed的使用总结

    本文主要介绍Vue.js中监听器和计算属性的相关知识点,包括对普通属性的监听、对对象的监听、对数组的监听,以及计算属性的Set方法,计算属性与监听器的区别等等
    2021-05-05
  • vue3 setup语法糖各种语法新特性的使用方法(vue3+vite+pinia)

    vue3 setup语法糖各种语法新特性的使用方法(vue3+vite+pinia)

    这篇文章主要介绍了vue3 setup语法糖各种语法新特性的使用(vue3+vite+pinia),本文主要是记录vue3的setup语法糖的各种新语法的使用方法,需要的朋友可以参考下
    2022-09-09
  • 浅谈基于Vue.js的移动组件库cube-ui

    浅谈基于Vue.js的移动组件库cube-ui

    这篇文章主要介绍了基于Vue.js的移动组件库cube-ui,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12
  • 浅析webpack-bundle-analyzer在vue-cli3中的使用

    浅析webpack-bundle-analyzer在vue-cli3中的使用

    这篇文章主要介绍了webpack-bundle-analyzer在vue-cli3中的使用,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-10-10
  • Echarts+VUE柱状图绘制细节并且屏幕自适应完整代码

    Echarts+VUE柱状图绘制细节并且屏幕自适应完整代码

    柱状图(或称条形图)是一种通过柱形的长度来表现数据大小的一种常用图表类型,这篇文章主要给大家介绍了关于Echarts+VUE柱状图绘制细节并且屏幕自适应的相关资料,需要的朋友可以参考下
    2024-02-02

最新评论