vite 构建实现增量更新

问题描述:

vite项目中,尽管每次只是部分文件更新,但构建之后,由于组件依赖关系,只要其中一个文件内容发生变化并且文件使用了[hash] 配置(相当于内容hash),其他文件的导入路径都会更新,导致内容变化,文件指纹也会变化。

解决思路:

vite 仓库相关 issue 和讨论 github.com/vitejs/vite...

主要是入口文件(entryFileNames)的路径名变化,影响绝大部分模块。 所以想要实现增量更新,这个入口文件名最好固定。

  1. 固定入口文件会导致浏览器缓存,整个应用都不再更新。
  2. 虽然可以在加载入口文件时加一个 query 时间戳。但是动态的组件中,对这个入口文件引用是不带query的,控制台会报错,页面会白屏。
  3. 要解决上面问题,就需要所有引用入口文件的地方,全部带上时间戳。可以借助 importmap 进行映射。实现一个 plugin,自动在入口文件后面拼接时间戳,同时在 head 头中注入 importmap。
ts 复制代码
entryFileNames: "assets/[name].main.js"
chunkFileNames: "assets/[name].[hash].js"
ts 复制代码
import type { Plugin } from 'vite'

export default function viteImportMapPlugin(): Plugin {
  return {
    name: 'html-entry-version-with-importmap',
    transformIndexHtml(html) {
      const version = Date.now()
      // 1. 给入口文件加 query
      const updatedHtml = html.replace(
        /(<script[^>]+src=")([^"]*main)(.js)"/,
        `$1$2.js?v=${version}"`
      )
      // 2. 在 HTML 中插入 importmap
      // 提取 main.js 路径(不带 query)
      const match = html.match(/<script[^>]+src="([^"]*main).js"/)
      if (!match) return updatedHtml
      const entryPath = match[1] + '.js'
      const entryWithVersion = `${entryPath}?v=${version}`
      const importmap = `\n  <script type="importmap">\n    {\n      "imports": {\n        "${entryPath}": "${entryWithVersion}"\n      }\n    }\n  </script>\n`
      // 3. 把 importmap 插入到 </head> 前
      return updatedHtml.replace('</head>', `${importmap}\n</head>`)
    }
  }
}

可能存在的问题:

  1. importmap 兼容性,如果浏览器不支持,需要使用 es-module-shims 进行 polyfill。并且这个文件需要写在头部,使用 async属性,因为 importmap 是静态映射表,加载完成后,无法热更新。
ts 复制代码
<script async src="/es-module-shims.min.js"></script>
  1. 不适合多入口文件(应该可搞),不支持 SSR等。
  2. 观察一段时间看看是否有副作用。

其他优化

  • 利用 manualChunks 进行三方包分割
相关推荐
计算机学姐10 小时前
基于微信小程序的高校班务管理系统【2026最新】
java·vue.js·spring boot·mysql·微信小程序·小程序·mybatis
哆啦A梦158814 小时前
点击Top切换数据
前端·javascript·vue.js
小光学长15 小时前
基于Vue的2025年哈尔滨亚冬会志愿者管理系统5zqg6m36(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
前端·数据库·vue.js
麦麦大数据16 小时前
D027 v2 vue+django+neo4j 基于知识图谱红楼梦问答系统 (新增问关系功能;新增知识节点和关系管理功能,neo4j增删改查功能)
vue.js·django·问答系统·知识图谱·neo4j·图谱管理·neo4j增删改查
菜鸟una17 小时前
【瀑布流大全】分析原理及实现方式(微信小程序和网页都适用)
前端·css·vue.js·微信小程序·小程序·typescript
专注前端30年18 小时前
2025 最新 Vue2/Vue3 高频面试题(10月最新版)
前端·javascript·vue.js·面试
我的div丢了肿么办19 小时前
js函数声明和函数表达式的理解
前端·javascript·vue.js
武天19 小时前
一个项目有多个后端地址,每个后端地址的请求拦截器和响应拦截器都不一样,该怎么封装
vue.js
潜心编码19 小时前
基于vue的停车场管理系统
前端·javascript·vue.js
三小河20 小时前
React Vite 中动态批量导入路由
前端·vue.js