Vite 依赖预构建缓存失效时的排查步骤
“我已经改了依赖,为什么 Vite 还在用旧代码?”遇到这类问题,先不要把 node_modules 整个删掉。Vite 的依赖预构建只发生在开发模式,异常通常落在三层之一:决定预构建结果的输入指纹、node_modules/.vite 文件系统缓存,或者浏览器对优化依赖请求的强缓存。先判断层级,再选择处理动作,通常几分钟内就能定位。
官方文档:https://vite.dev/guide/dep-pre-bundling
先确认失效发生在哪一层
Vite 首次启动开发服务器时,会扫描源码里的裸模块导入,并把发现的依赖预构建后写入 node_modules/.vite。它既要把 CommonJS、UMD 依赖转换成开发环境可使用的 ESM,也会把内部模块很多的 ESM 依赖合并,减少浏览器请求数量。
因此,“缓存失效”并不是一个单点问题。可以先按现象做快速判断:
- 每次启动都重新执行依赖优化:优先检查锁文件、补丁目录、Vite 配置或
NODE_ENV是否持续变化。 - 终端显示已经重新优化,但页面仍像旧版本:优先排查浏览器缓存。
- 新增依赖后启动阶段发生第二次重载:多半是初始扫描没有发现该依赖。
- 本地链接包修改后没有生效:需要检查 linked package 的 ESM 形态,并主动强制重新优化。

图1:Vite 依赖预构建的输入指纹、磁盘缓存与浏览器缓存三层结构。
Vite 依据什么判断需要重新预构建
官方文档列出的文件系统缓存输入包括包管理器锁文件内容、依赖补丁目录的修改时间、vite.config 中影响依赖优化的字段,以及 NODE_ENV。只要这些输入发生变化,下一次启动就可能重新执行预构建。反过来说,如果你修改的是不会进入这些输入的本地链接关系,Vite 也可能不知道需要更新。
排查时先比较“上一次正常启动”和“当前启动”之间发生了什么,而不是直接清空所有依赖:
# 查看锁文件是否出现了意外改动 git diff -- package-lock.json pnpm-lock.yaml yarn.lock # 查看 Vite 配置是否被脚本或环境变量改写 git diff -- vite.config.js vite.config.ts # 确认当前开发进程使用的环境值 echo "$NODE_ENV"
如果团队成员的包管理器版本不同,锁文件格式或内容可能反复变化;如果 Vite 配置根据时间、随机值或机器路径生成 optimizeDeps,也会让依赖哈希不稳定。应当修复这些输入,而不是把清缓存写成每次启动都执行的脚本。
怎样用最短路径恢复一次正确预构建
确认依赖内容确实改变后,优先使用 Vite 提供的 --force。它会忽略已有的优化依赖缓存并重新预构建,比删除整个 node_modules 更小、更可控。
# 直接启动 Vite,并强制重新执行依赖预构建 npx vite --force # 通过项目中的 dev 脚本把 --force 继续传给 Vite npm run dev -- --force
如果项目需要临时通过配置强制优化,也可以使用 optimizeDeps.force。不过它适合短期诊断,不建议长期保持为 true,否则每次启动都会失去缓存收益。
import { defineConfig } from 'vite'
export default defineConfig({
optimizeDeps: {
// 仅用于定位缓存问题,确认后应改回 false 或删除该项
force: true,
},
})
若强制预构建后页面仍然显示旧代码,要处理浏览器这一层。Vite 会给已解析的依赖请求设置长期强缓存,并通过 URL 上的版本查询参数自动失效。调试本地依赖时,可临时在开发者工具的 Network 面板禁用缓存,随后用 --force 重启 Vite,再重新加载页面。只删 node_modules/.vite 而不刷新浏览器,可能仍看到旧响应。
配置导致的重复预构建怎么处理
Vite 默认扫描 HTML 入口;如果配置了构建输入,则使用对应入口。当插件转换、按条件加载或深层导入让依赖无法在初始扫描中出现时,开发服务器启动后才发现新依赖,就可能立即重新预构建并触发页面重载。
optimizeDeps.entries 用于明确扫描入口,include 用于强制预构建依赖,exclude 则让适合直接由浏览器加载的小型 ESM 依赖留在优化范围之外。CommonJS 依赖不应直接排除;如果被排除的 ESM 依赖内部又依赖 CommonJS,应把嵌套 CommonJS 依赖加入 include。
import { defineConfig } from 'vite'
export default defineConfig({
optimizeDeps: {
// 覆盖默认入口推断,显式扫描应用与管理端入口
entries: ['index.html', 'admin/index.html'],
// 强制预构建扫描阶段难以发现或属于 CommonJS 的依赖
include: ['linked-ui-kit', 'esm-wrapper > legacy-cjs-lib'],
// 只排除体积小且原生 ESM 完整的依赖
exclude: ['tiny-esm-helper'],
},
})

图2:Vite 入口扫描、优化配置和依赖类型之间的静态边界关系。
monorepo 和本地链接包为什么更容易出问题
在 monorepo 中,Vite 会把不从 node_modules 解析出来的 linked package 当作源码处理,默认不会预构建它,而是继续分析其依赖列表。这个 linked package 应当能以 ESM 形式使用;如果它不是 ESM,可以把包名加入 optimizeDeps.include 强制预构建。
修改 linked package 后,应使用 --force 重启开发服务器。Vite 的故障排查文档还特别指出,使用 npm link 建立或解除链接时,缓存不会仅凭链接关系自动失效。能使用包管理器 overrides 或 resolutions 表达依赖替换时,这种方式更容易被锁文件记录,也更利于团队复现。
# linked package 改动后,强制生成新的优化依赖 npm run dev -- --force # 在 pnpm 工作区中确认实际解析到的依赖版本 pnpm why linked-ui-kit
有哪些常见误区
误区一:任何异常都删除 node_modules
删除全部依赖会掩盖真正变化的输入,还会引入重新安装带来的锁文件或平台差异。优先使用 --force,必要时只删除 node_modules/.vite。
误区二:把 optimizeDeps.force 永久打开
这会让开发启动反复付出预构建成本。正确做法是用它验证缓存是否为原因,然后修正锁文件、配置或依赖发现边界。
误区三:把 CommonJS 依赖放进 exclude
开发环境以原生 ESM 提供代码,CommonJS 依赖需要经过优化转换。应优先放入 include,而不是绕过预构建。
一份可复用的排查清单
- 记录现象:是每次启动都重建、启动后二次重载,还是页面仍显示旧依赖。
- 检查锁文件、补丁目录、Vite 配置与
NODE_ENV是否发生预期外变化。 - 用
npm run dev -- --force做一次最小范围的强制预构建。 - 在浏览器开发者工具中临时禁用缓存,并重新加载页面。
- 若启动后才发现依赖,用
entries或include固化扫描范围。 - 若是 monorepo 链接包,确认其 ESM 输出;否则加入
include,修改后用--force重启。 - 最后再考虑删除
node_modules/.vite,通常无需重装全部依赖。
延伸问题
预构建缓存会影响生产构建吗?
不会直接影响。Vite 的依赖预构建器只用于开发模式,生产构建走独立的构建链路。遇到生产包异常,应从构建配置、插件和产物缓存另行排查。
可以直接删除 node_modules/.vite 吗?
可以,官方也把它列为强制重新预构建的方法之一。但日常排查优先使用 --force,命令意图更明确,也方便写入复现步骤。
为什么改了本地依赖,版本查询参数没有变化?
版本查询参数与预构建结果及锁文件信息相关。本地链接关系尤其是 npm link 的变化,不一定进入自动失效输入,因此要用 --force 重新优化,并同步刷新浏览器缓存。
归根结底,Vite 预构建缓存排查的关键不是“删得更彻底”,而是明确哪一层没有感知变化:输入指纹稳定性、磁盘优化结果、浏览器强缓存,还是依赖扫描边界。按层处理,既能快速恢复开发环境,也能避免把缓存清理变成长期负担。
诗歌本内容分级怎么看?Google Play家庭政策与数据安全说明
- 上一篇
- 诗歌本内容分级怎么看?Google Play家庭政策与数据安全说明
- 下一篇
- Go build -overlay 临时替换源码的调试方法
-
- 文章 · 前端 | 1天前 |
- 表单 aria-describedby 关联错误提示的可访问设计
- 349浏览 收藏
-
- 文章 · 前端 | 1天前 | 前端 · css · 组合选择器 CSS :is specificity :where 级联层
- CSS :is 组合选择器时的 specificity 控制
- 327浏览 收藏
-
- 文章 · 前端 | 2天前 | javascript · DNS耗时 PerformanceResourceTiming TLS耗时
- PerformanceResourceTiming 拆分 DNS 与 TLS 耗时
- 108浏览 收藏
-
- 文章 · 前端 | 4天前 | 前端 · websocket ·
- WebSocket 重连退避与页面卸载的收尾
- 381浏览 收藏
-
- 文章 · 前端 | 4天前 |
- Fetch keepalive 处理页面卸载前的小请求
- 291浏览 收藏
-
- 文章 · 前端 | 4天前 |
- CSS @scope 限定组件样式作用域的迁移方法
- 294浏览 收藏
-
- 文章 · 前端 | 4天前 |
- View Transition API 在 SPA 状态切换中的降级方案
- 142浏览 收藏
-
- 文章 · 前端 | 5天前 | javascript · 表单 · FormData FormDataEvent formdata事件 原生表单
- FormDataEvent 统一拦截原生表单数据的实现
- 288浏览 收藏
-
- 文章 · 前端 | 5天前 | html · javascript · 表单 · requestSubmit form.submit HTML表单校验
- requestSubmit 与 form.submit 有什么区别
- 392浏览 收藏
-
- 文章 · 前端 | 5天前 |
- scheduler.yield 怎么把长任务拆开又保持优先级
- 110浏览 收藏
-
- 文章 · 前端 | 5天前 | CSS 滚动动画 animation-timeline scroll-timeline
- CSS scroll-timeline 怎么驱动滚动进度动画
- 251浏览 收藏
-
- 文章 · 前端 | 5天前 |
- IntersectionObserver scrollMargin 怎么处理嵌套滚动容器
- 380浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 316次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 374次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 370次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 336次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 162次使用
-
- Vite 8 升级怎么做:Rolldown、Oxc 与 CommonJS 兼容的迁移清单
- 2026-07-17 248浏览
-
- 前端 import.meta.dirname 怎么替代路径拼接:Node.js ESM 文件定位、兼容边界与构建发布
- 2026-08-26 384浏览
-
- Vite 8.1 插件兼容怎么查:Rolldown 迁移、警告信息与回退边界
- 2026-09-03 112浏览

