| 现象 | 原因 | 解决 |
|---|---|---|
| 改文件页面不刷新 | WSL / Docker 文件系统 inotify 失效 | server.watch.usePolling: true(性能差,本地原生不要开) |
| 状态被重置 | 改了非组件文件(store / util),HMR 整页刷新 | 正常行为,把状态放 Zustand 持久化 |
[hmr] Failed to reload xxx | 文件有语法错误 | 先修语法,看 Vite 终端报错 |
| 改 CSS 不更新 | CSS 引入方式是 import.meta.glob 或动态 import | 改静态 import |
| 改 antd 主题不生效 | ConfigProvider 在 effect 里赋值,HMR 不重新执行 | 把主题配置放进组件 props |
| 浏览器 hot 客户端连不上 | 反向代理没转发 /__vite_ping | nginx 配 ws 转发或 dev 直连 5173 |
7.1 HMR 工作原理(理解后才好排错)
- Vite 修改文件 → 通过 ws 发
update消息到浏览器 - 浏览器收到 → fetch 新模块 → 替换 module graph
- 找到能接受热更的边界(
import.meta.hot.accept),停在那里 - React 组件由
@vitejs/plugin-react注入 fast-refresh,保留 state
关键概念:HMR 找不到接受边界就整页刷新,state 丢失,这是降级而非 bug。
7.2 让自定义 module 支持 HMR
// 自己的 store / util 想热更不丢状态
if (import.meta.hot) {
import.meta.hot.accept((newMod) => {
// 处理新模块
});
}
7.3 React Fast Refresh 失效的常见原因
- 文件里同时 export 组件和非组件(常量 / hook 工厂)
- 组件用
export default function,改成export default Foo命名引用 - 文件不是
.tsx/.jsx,被识别为普通模块
修法:一个文件只 export 一个组件;hook / util 拆到独立文件。