devtools

devtools

熱門

開箱即用的 json-render 應用程式除錯面板。當使用者想要除錯生成式 UI、檢視 spec 樹狀結構、在執行階段編輯狀態、查看已發送的 action、即時追蹤串流 patch、瀏覽 catalog,或是透過點選 DOM 元素來尋找其 spec key 時使用。觸發語句包含「新增 devtools」、「除錯 json-render」、「檢視 spec」、「為什麼這個元素沒有渲染」、「查看執行階段狀態」,或要求為 `@json-render/devtools` 擷取串流 / 記錄 action 紀錄等。

1.6萬星標
852分支
更新於 2026/7/8
SKILL.md
唯讀
名稱
devtools
描述

開箱即用的 json-render 應用程式除錯面板。當使用者想要除錯生成式 UI、檢視 spec 樹狀結構、在執行階段編輯狀態、查看已發送的 action、即時追蹤串流 patch、瀏覽 catalog,或是透過點選 DOM 元素來尋找其 spec key 時使用。觸發語句包含「新增 devtools」、「除錯 json-render」、「檢視 spec」、「為什麼這個元素沒有渲染」、「查看執行階段狀態」,或要求為 `@json-render/devtools` 擷取串流 / 記錄 action 紀錄等。

@json-render/devtools

專為 json-render 應用程式打造的浮動式除錯面板。提供跨框架的核心庫,並針對不同框架(React、Vue、Svelte、Solid)提供相應的 Adapter。

生產環境安全:當 NODE_ENV === "production" 時,此元件會直接渲染為 null

安裝

安裝核心套件以及與主應用程式渲染器匹配的 Adapter。

# React
npm install @json-render/devtools @json-render/devtools-react

# Vue
npm install @json-render/devtools @json-render/devtools-vue

# Svelte
npm install @json-render/devtools @json-render/devtools-svelte

# Solid
npm install @json-render/devtools @json-render/devtools-solid

開箱即用

<JsonRenderDevtools /> 放置在現有 <JSONUIProvider>(或相應框架的等效 Provider)內部的任何位置即可,無需額外配置。

React

import { JsonRenderDevtools } from "@json-render/devtools-react";

<JSONUIProvider registry={registry} handlers={handlers}>
  <Renderer spec={spec} registry={registry} />
  <JsonRenderDevtools spec={spec} catalog={catalog} messages={messages} />
</JSONUIProvider>;

Vue

<script setup>
import { JsonRenderDevtools } from "@json-render/devtools-vue";
</script>

<template>
  <JSONUIProvider :registry="registry">
    <Renderer :spec="spec" :registry="registry" />
    <JsonRenderDevtools :spec="spec" :catalog="catalog" :messages="messages" />
  </JSONUIProvider>
</template>

Svelte

<script>
  import { JsonRenderDevtools } from "@json-render/devtools-svelte";
</script>

<JSONUIProvider {registry}>
  <Renderer {spec} {registry} />
  <JsonRenderDevtools {spec} {catalog} {messages} />
</JSONUIProvider>

Solid

import { JsonRenderDevtools } from "@json-render/devtools-solid";

<JSONUIProvider registry={registry}>
  <Renderer spec={spec()} registry={registry} />
  <JsonRenderDevtools
    spec={spec()}
    catalog={catalog}
    messages={messages()}
  />
</JSONUIProvider>;

操作控制

  • 右下角顯示浮動切換按鈕。
  • 快捷鍵:Ctrl/Cmd + Shift + J(可透過 hotkey prop 自訂)。
  • 抽屜式面板支援拉伸調整大小,且高度設定會自動儲存至 localStorage

Props

  • spec (Spec | null) — 當前 spec。
  • catalog (Catalog | null) — catalog 定義;Catalog 面板所必需的屬性。
  • messages (UIMessage[]) — AI SDK useChat 的訊息陣列;會自動掃描其中的 spec 資料片段。
  • initialOpen (boolean) — 預設是否展開面板。
  • position ("bottom-right" | "bottom-left" | "right") — 面板停靠位置與切換按鈕角落。"bottom-*" 停靠於底部;"right" 則以全高停靠於右側邊緣(推薦用於已使用 100vh 或固定底部列的 App Shell 布局)。
  • hotkey (string | false) — 預設為 "mod+shift+j"
  • bufferSize (number) — 事件環形緩衝區上限,預設為 500。
  • reserveSpace (boolean, 預設為 true) — 為 true 時,面板會透過在 body 上施加 padding-bottom / padding-right 來推開主應用程式內容。設為 false 則將面板作為純粹的浮層 (overlay)。
  • allowDockToggle (boolean, 預設為 true) — 在工具列顯示按鈕,允許使用者在底部停靠與右側停靠之間切換。使用者的選擇會持久化儲存於 localStorage,並在後續掛載時覆蓋 position 設定。傳入 false 則可鎖定面板停靠於 position 指定的位置。
  • onEvent ((DevtoolsEvent) => void) — 可選的事件監聽/攔截回調函式。

面板功能

  • Spec — 以 spec.root 為根節點的元素樹;顯示 props、可見性 (visibility)、事件 (events) 與監聽器 (watchers) 的詳細資訊;整合 validateSpec 警告訊息。
  • State — 條列所有 JSON Pointer 路徑,並支援透過 store.set 進行行內 (inline) 編輯。
  • Actions — 已發送 action 的時間軸(包含名稱、參數、結果/錯誤、執行耗時)。
  • Stream — 按生成批次分組顯示 spec patch、文本區塊、token 用量及生命週期標記。
  • Catalog — 顯示在 catalog 中聲明的元件與 action,並附帶 prop 標籤。

元素選擇器 (Picker 工具列)

元素選擇器是面板頂欄中的一個工具列按鈕(類似 Chrome DevTools 的設計),而非獨立分頁。點擊按鈕即可啟動選取模式,接著點擊頁面中任何已渲染的元素,畫面就會自動跳轉至 Spec 分頁並聚焦該元素。按下 Esc 即可取消選取。

空間預留與面板停靠

面板可停靠於頁面底部或右側邊緣。預設情況下,使用者可以透過工具列按鈕在兩者之間自由切換(該選擇會儲存於 localStorage)。如果主應用程式僅相容單一停靠模式,可設定 allowDockToggle={false},按鈕將被隱藏,並固定停靠於 position 設定的位置。

根據您的頁面布局選擇合適的初始停靠位置:

  • 底部停靠(預設) — 最適合文件 / 行銷 / 內容流網站,以及透過 height: 100% 鏈結建構的 App Shell(html { height: 100% }body { height: 100% }.app { height: 100% })。面板會將其高度寫入 --jr-devtools-offset-bottom,並在 body 上套用對應的 padding-bottom,讓非固定定位的內容自然空出空間。
  • 右側停靠 (position="right") — 推薦用於採用 100vhposition: fixed; bottom: 0 的 App Shell 布局。右側停靠可完全避開底部邊緣,並改為將面板寬度寫入 --jr-devtools-offset-right

使用 100vhposition: fixedposition: sticky 的應用程式,可以使用套件釋出的 CSS 自訂屬性來為特定元素手動對齊:

.composer   { bottom: var(--jr-devtools-offset-bottom, 0); }
.sidebar    { right:  var(--jr-devtools-offset-right,  0); }
.app-shell  { height: calc(100vh - var(--jr-devtools-offset-bottom, 0)); }

若自動設定的 body padding 對特定布局造成干擾,可傳入 reserveSpace={false} 將面板轉為純覆蓋層 (overlay) — 此時 CSS 自訂屬性仍會持續發布,以便您進行手動空間預留。

(保留 --jr-devtools-offset 作為當前有效邊緣的向後相容別名。)

單頁面多重渲染器(例如聊天介面)

單一 <JsonRenderDevtools /> 實例即可同時檢視多個 <Renderer /> 實例 — 例如每個 AI 訊息各渲染自身 spec 的聊天介面,或是由多個獨立 Widget 組成的儀表板。配置方式如下:

  1. 單一最上層 <JSONUIProvider>:確保所有渲染器共享同一個 state store 與 action dispatcher。Devtools 位於此 Provider 內部,藉此掌握整體全貌。
  2. 各渲染器獨立 spec、共享 state:每個 AI 訊息直接渲染 <Renderer spec={msgSpec} registry={registry} />,無需包裹在獨立的 StateProvider 中。請注意不同訊息的 state 路徑切勿發生碰撞衝突。
  3. 為每輪對話加上 State 命名空間:當資料來源為 AI 串流時,傳遞獨立的 messageId 給 Agent,並要求所有元素 key(例如 <id>-root)與 state 路徑(例如 /<id>/count)皆必須加上該 ID 作為前綴。
  4. 傳入 spec={latest} + messages={all}spec 用於驅動 Spec 面板(通常傳入最新訊息的 spec),而 messages 則為 Stream 面板提供來自每一輪對話的 patch 資料。
  5. Action 與 Picker 本身即具備全域特性registerActionObserver 能擷取元件樹中任何 ActionProvider 所發送的 action,且 data-jr-key 是由渲染器本身寫入的,因此不論元素是由哪一條訊息生成,Picker 功能都能完美運作。

參閱 examples/devtools 可查看依照此方式配置的完整 AI 聊天實例。

命令式 API(僅限 React)

import { useJsonRenderDevtools } from "@json-render/devtools-react";

const devtools = useJsonRenderDevtools();
devtools?.open();
devtools?.toggle();
devtools?.recordEvent({ kind: "stream-text", at: Date.now(), text: "hi" });

在生產環境或元件掛載完成之前會傳回 null

伺服器端串流攔截 (Stream tap)

在 API 路由擷取 spec patch,使事件得以持久化儲存於伺服器端,或串接至您自訂的遙測系統 (telemetry)。

import { tapJsonRenderStream, createEventStore } from "@json-render/devtools";
import { pipeJsonRender } from "@json-render/core";

const events = createEventStore({ bufferSize: 1000 });
const tapped = tapJsonRenderStream(result.toUIMessageStream(), events);
writer.merge(pipeJsonRender(tapped));

YAML 等效 API:tapYamlStream

底層運作原理

  • Shadow DOM 樣式隔離面板 — 面板的樣式絕不會滲漏至主應用程式中,反之亦然。
  • 環形緩衝事件儲存區 (Ring-buffered event store) — 設有數量上限的 devtools 事件日誌(記錄狀態變更、action 發送、串流 patch 等)。
  • Action 觀察者註冊表 — 各框架的 ActionProvider 會透過 @json-render/core 中的 notifyActionDispatch / notifyActionSettle 發送通告;Devtools 則透過 registerActionObserver 進行訂閱。
  • Picker 元素標籤化 — 當 Devtools 掛載時,ElementRenderer 會將每個渲染出的元素包裹在 <span data-jr-key="..." style="display:contents"> 中,藉此讓 Picker 能精確完成 DOM → spec key 的映射,且完全不影響版面布局。