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 进行三方包分割
相关推荐
宿67413 小时前
vue3-env环境
前端·vue.js
汉堡大王952713 小时前
Vue 3 + TS + Element Plus 实战:如何从零搭建企业级违章记录管理 SaaS 前端
前端·javascript·vue.js
障碍的枫子18 小时前
Vue组件导出&渲染
前端·javascript·vue.js
Sterting18 小时前
组件通信:Props 与 Emit
前端·vue.js
喵个咪19 小时前
GoWind Shop 架构剖析:一个 REST 请求穿越三服务 BFF 的七环链路
vue.js·后端·go
喵个咪19 小时前
GoWind Shop 安全设计:JWT 鉴权、Ent 行级隔离、防篡改审计与四个真实漏洞修复
vue.js·后端·go
喵个咪19 小时前
GoWind Shop:一个 proto 文件如何生成后端、前端、文档、校验六路代码
vue.js·后端·go
喵个咪19 小时前
GoWind Shop 出海实战:多语言商品内容怎么存、怎么录、怎么按 locale 取
vue.js·后端·go
No Silver Bullet20 小时前
Vue进阶(贰幺叁)vue.config.js 中 productionSourceMap 作用详解
前端·javascript·vue.js
xcsweb20 小时前
从5分钟到10秒:我用一个Skill把团队部署效率提升了30倍
前端·vue.js