HMR 是为人类设计的,不是为 Agent 设计的

next-browser 证明了「structured CLI + agent skill」是正确方向。把这套架构移植到 Vite 的过程里,我遇到了一个 Next.js 不需要面对的问题。


从 next-browser 说起

如果你用过 Claude Code 或 Cursor 来修 Next.js 项目,可能见过这个:

r 复制代码
npx skills add vercel-labs/next-browser

Vercel Labs 做的 next-browser,核心思路是:LLM 看不懂 DevTools 面板,但可以跑 next-browser tree,解析结构化输出,再决定下一步看什么。

每条命令是一次无状态调用,打给一个长驻的 browser daemon。Agent 不需要管浏览器生命周期,只管拿结构化文本做推断。

这个设计很对。我用了之后,第一反应是:Vite 生态里没有对应的东西。

Vue、React(非 Next.js)、Svelte------用 Vite 的项目没有 next-browser 这样的工具。所以我做了 vite-browser,把这套架构移植过来。

移植的过程里,我遇到了一个结构性的问题。


next-browser 能做到的事,在 Vite 里没有对应的基础设施

next-browser 的诊断能力建立在 Next.js 自己暴露的接口上:errors、logs、routes 这些走的是 /_next/mcp,一个 Next.js dev server 内置的诊断端点,响应是结构化的 JSON-RPC。PPR 诊断用的是 Next.js 专用的 cookie 机制。React 组件树靠预注入的 DevTools hook 直接读 renderer interface。

next-browser 的哲学是:让 HMR 自己工作,通过框架暴露的诊断接口观察结果。 文档里直接写了「HMR picks up code changes on its own」。

这个哲学在 Next.js 上完全成立,因为框架本身就提供了足够丰富的结构化诊断信息。

Vite 没有这层。

Vite 没有 /_vite/mcp。没有内置的诊断端点。HMR 的全部信息都在一条 WebSocket 连接里,以帧的形式推送,消费完就消失。

所以当 Agent 事后介入,问「刚才那次热更新更新了哪些模块、有没有导致这个报错」------这个问题在 Vite 里根本没有现成的接口可以回答。


HMR 是 push-based 的,Agent 是 pull-based 的

Vite 的 HMR 是 push-based + ephemeral------WebSocket 推送,即时消失。信息在出现的瞬间被消费,然后没了。这套机制为人类设计:你在屏幕前,报错弹出来,刚改的文件还记得,上下文全在脑子里。

Agent 是 pull-based + invoked after the fact------查询式,事后介入。用户页面坏了才来找 Agent,这时候 HMR 事件已经消失:

  • 没有「过去几秒更新了哪些模块」的结构化 API
  • 报错告诉你 TypeError: Cannot read properties of undefined,但不告诉你是哪次更新造成的
  • Agent 拿到的只有一个静态错误快照,和大量猜测空间

更关键的是:Agent 要生成有效的修复,需要知道 root cause,不只是 error location。HMR 给的精度够人类「大概猜到哪里」,但不够 Agent 以高置信度确定「是 cart.tsitems 这个 key 的变更,断掉了 AppShell > ShoppingCart > CartSummary 这条渲染路径」。

这个精度差距,才是 Agent 修 Vite 项目时反复兜圈子的真正原因。

要解决这个问题,需要在 HMR 事件发生时就把它持久化:尽早挂接到 Vite HMR client(window.__vite_hot.ws),持续监听消息并记录下来,同时保留 console 日志作为 fallback。 这样 Agent 事后介入时,才有历史事件可以查询。

这是 vite-browser 必须做、next-browser 不需要做的事。


vite-browser 做了什么

vite-browser 在 next-browser 的架构基础上,补上了 HMR 这一层。

核心:把 Vite 的 ephemeral event stream 转化成 Agent 可以反复 query 的结构化证据。

零配置,不改项目,连接正在运行的 Vite dev server 就可以用。

一个前提:vite-browser 需要在开发过程中保持连接,才能持续记录 HMR 事件流。如果页面坏了之后才开 vite-browser,之前的 HMR 历史已经消失,关联分析会拿不到数据。工作方式是:开一个终端跑 dev server,开另一个终端连 vite-browser,然后正常开发。

Vue 项目开箱即用。React + Zustand 项目需要 store 在 window.__ZUSTAND_STORES__ 下可被发现(多数标准配置下满足),否则 store 相关命令会跳过。

一个典型的场景------页面在热更新后挂了,走这三步(以 React 项目为例,Vue + Pinia 输出格式相同):

arduino 复制代码
# 1. 看报错,带 source map 和内联源码
$ vite-browser errors --mapped --inline-source

TypeError: Cannot read properties of undefined (reading 'items')
  → /src/components/CartSummary.tsx:14:12
    14 | total = cart.items.reduce(...)
sql 复制代码
# 2. 把报错和近期 HMR 更新关联
$ vite-browser correlate errors --mapped --window 5000

Confidence: high
HMR update observed within 5000ms of the current error
Matching modules: /src/store/cart.ts
yaml 复制代码
# 3. 追踪传播路径
$ vite-browser diagnose propagation --window 5000

Status: fail | Confidence: high
Store → Render → Error path found:
  store: cart (changedKeys: items)
  render: AppShell > ShoppingCart > CartSummary

三条命令,缩小范围了:cart.tsitems 的变更是最可能的原因,渲染路径断在 CartSummary。这是有置信度的证据链,不是因果证明------文档里明确把它定位成「high-confidence narrowing tool」,不是 proof engine。证据足够让 Agent 有方向地生成修复,而不是瞎猜。


补上视觉这一环

结构化输出能告诉 Agent「报错消了」,但不能告诉它「页面看起来对不对」。

布局错位、样式回归、数据展示异常------这些问题在日志里是沉默的。Agent 修完之后,只知道没有 JS 报错,不知道页面是不是真的好了。

r 复制代码
vite-browser screenshot

全页截图,直接输出给多模态 Agent。Agent 用视觉判断修复是否符合预期,或者发现只有「看」才能发现的回归。

结构化证据 + 视觉证据 = 完整的 observation layer。


Agent Skill Router

vite-browser 同样基于 skills.sh 生态分发,通过 skill router 针对 Vite 的调试场景做了路由分层:

bash 复制代码
npx skills add MapleCity1314/vite-browser

安装之后,Agent 拿到的不是一堆命令,而是一个决策树:

症状 路由到
宽泛或不明确的失败 core-debug
改了代码,HMR 之后挂了 runtime-diagnostics
数据不对,接口有问题 network-regression
merge 前验证 release-smoke

每个 skill pack 里有结构化的 workflow,告诉 Agent 按什么顺序跑什么命令,在什么条件下升级到下一步。

Agent 擅长按结构化流程执行,不擅长从零设计调试策略。 Skill router 解决的是后者。


支持范围(v0.3.6)

Vue + Pinia

  • 组件树、Pinia store 状态、Vue Router
  • HMR 与报错的时间窗口关联
  • store → render → error 路径追踪(通过 Pinia $subscribe/$onAction 注入采集 store 更新事件)

React + Zustand

  • 组件树
  • Zustand store 发现和状态读取(依赖 window.__ZUSTAND_STORES__ 可被发现)
  • 内置 DevTools hook,零配置,不需要浏览器扩展
  • hook 诊断、commit 追踪
  • 注:React 侧的 store → render → error 完整传播链追踪还在 roadmap 中

Svelte

  • 组件树检查

通用

  • Source-mapped 报错,带内联源码片段
  • HMR 模式诊断(missing-modulecircular-dependencyhmr-websocket-closed
  • screenshot 全页截图

这只是第一步

vite-browser 现在做的是 observation layer:结构化运行时状态,让 Agent 能以高置信度定位 root cause。

完整的自主修复 pipeline 应该是这样的:

css 复制代码
[观察] vite-browser  →  结构化证据,root cause 定位
[推断] Agent         →  生成 patch.diff
[执行] dev sandbox   →  隔离环境 apply patch
[验证] vite-browser  →  确认修复,screenshot 验证视觉

observation → patch → verify,vite-browser 是第一环。next-browser 的 patch apply 方向(cat <<'PATCH' | npx next internal apply)给了很好的参考,Vite 侧的对应实现还在探索中。


装起来

bash 复制代码
# Agent Skill 方式(推荐,Claude Code)
npx skills add MapleCity1314/vite-browser

# 或只用 CLI
npm install -g @presto1314w/vite-devtools-browser
npx playwright install chromium

要求:Node.js ≥ 20,一个正在运行的 Vite dev server。

基本流程:

r 复制代码
vite-browser open http://localhost:5173
vite-browser detect
vite-browser errors --mapped --inline-source
vite-browser correlate errors --mapped --window 5000
vite-browser diagnose propagation --window 5000
vite-browser close

GitHub:MapleCity1314/vite-browser 文档:maplecity1314.github.io/vite-browse... npm:@presto1314w/vite-devtools-browser

如果这个方向对你有用,star 是最好的支持。

相关推荐
吃素的老虎2 小时前
从零构建 AI 网关(三):渠道插件系统
前端
学以智用2 小时前
# Vue3 路由(Vue Router 4)完全指南
前端·vue.js
anyup2 小时前
弃用 vue-i18n?只用 uView Pro 我照样做国际化!
前端·架构·uni-app
大漠_w3cpluscom2 小时前
利用现代 CSS 实现区间选择
前端·css·html
吃素的老虎2 小时前
从零构建 AI 网关(一):WebSocket 服务器实战
前端
酉鬼女又兒2 小时前
HTML基础实例样式详解零基础快速入门Web开发(可备赛蓝桥杯Web应用开发赛道) 助力快速拿奖
前端·javascript·职场和发展·蓝桥杯·html·html5·web
Watermelo6172 小时前
【前端实战】构建 Vue 全局错误处理体系,实现业务与错误的清晰解耦
前端·javascript·vue.js·信息可视化·性能优化·前端框架·设计规范
A923A2 小时前
【Vue3大事件 | 项目笔记】第二天
前端·vue.js·笔记·前端框架·前端项目
万码社3 小时前
小程序开发实战:我手写日历组件踩过的那些坑
前端