Vite HMR 失效主因是配置、路径或代码写法问题:server.watch.ignored 误排除有效路径;文件引用大小写与实际不符;模块未用 import.meta.hot.accept 声明更新;或编辑器未真正写入文件。

Vite 的 HMR 失效,通常不是“坏了”,而是某个环节被悄悄绕过或拦下了。它不报错、不崩溃,只是安静地不响应——这恰恰说明问题藏在配置、路径、代码写法这些看似琐碎却关键的地方。
server.watch.ignored 配置误伤有效路径
这是最隐蔽也最高频的元凶。Vite 默认用 chokidar 监听文件变更,而 ignored 规则一旦写得过于宽泛,就会直接让变更事件“石沉大海”。
- 常见错误写法:
ignored: ['lib/**', 'src/api/**']—— 如果你的 API 文件正在开发中,这条规则会把它整个目录排除在监听之外 - 软链接(npm link / ln -s)目录尤其危险:Vite 监听的是符号链接路径,但实际变更发生在真实路径;若真实路径被默认忽略项(如
**/node_modules/**)意外覆盖,热更新就断了 - 修复建议:删掉笼统的 ignore,改用精准排除 + 显式放行,例如:
ignored: ['!**/src/api/**', '!**/my-internal-pkg/src/**']
文件路径与引用大小写不一致
开发环境(尤其是 macOS / Windows)对大小写不敏感,但 Vite 的模块图和 HMR 机制是严格按路径字符串匹配的。一个字母大小写错,就等于指向了另一个模块。
- 典型场景:路由中写
import('@/views/User/index.vue'),但实际目录是user/(小写) - VSCode 自动补全可能帮你生成大写路径,而磁盘里是小写文件夹,保存后文件系统没变化,Vite 就收不到变更事件
- 验证方法:在浏览器控制台执行
import.meta.url,对比显示路径和你 import 的路径是否完全一致(含大小写)
模块未正确声明接受更新(import.meta.hot.accept)
Vite 的 HMR 是“推+拉”结合:服务端推送变更,客户端必须主动 声明接受,否则不会触发替换逻辑。普通 JS/TS 工具模块默认不参与 HMR 链路。
- Vue 单文件组件自动支持,但如果你在
<script setup></script>中做了副作用初始化(如定时器、事件监听),需手动用import.meta.hot.accept清理旧实例 - 工具函数、状态管理模块(如
store.ts)必须显式加:import.meta.hot?.accept(() => { /* 重置导出对象或重新初始化 */ }) - 若模块被间接使用(如通过
app.config.globalProperties挂载),HMR 不会追踪到它——确保它是被直接import的
开发工具未真正写入文件
HMR 依赖操作系统发出的文件变更通知(inotify / FSEvents)。如果编辑器只是把内容暂存在内存里,没落盘,Vite 就永远等不到那个“change”事件。
- VSCode 默认关闭自动保存,务必设为
onFocusChange或afterDelay - 某些编辑器插件(如 Prettier 格式化时机、GitLens 预览)可能延迟写入,可临时禁用验证
- 终端里用
echo "test" >> src/utils/test.ts手动触发一次变更,看是否恢复热更新——能恢复,基本锁定是编辑器保存问题


















