vtable-browser-debugger-assistant について
VTable 開発者向けのブラウザデバッグスキルです。Canvas、Scenegraph、DOM オーバーレイ、React 互換性の問題を再現・検証する手順を扱います。
主な機能
- 01VTable の問題の再現と検証
- 02Scenegraph のグループとノードの確認
- 03ノード境界と画面座標の比較
- 04React 18/19 の差異の調査
- 05操作状態と実行時値の確認
活用シーン
- 01表の空白表示やセルずれの調査
- 02固定領域やオーバーレイ表示異常の特定
- 03custom-layout の React 互換性の調査
MCP 対応
Chrome DevTools MCP でブラウザに接続し、スクリプト評価、実行時設定の変更、ブレークポイント、Scenegraph の出力を使って調査する手順を示します。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ visactor/ vtable --skill vtable-browser-debugger-assistantインストール後、Claude Code で/vtable-browser-debugger-assistantを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/react18-react19.mdsnippets.mdvrender-graphics.mdvtable-scenegraph.md詳細
VTable ブラウザーデバッガースキル
使用シーン
以下の問題が発生したときに、このスキルを使用します:
- ページが真っ白/テーブル領域が空白:canvas は存在するが内容が描画されない、または一部の領域(ヘッダー/固定領域/本文)が表示されない
- セルの内容が欠落する、位置がずれる、サイズが異常になる、固定領域の位置がずれる、hover/selection 枠の位置が異常になる
- カスタムレンダリングの異常:custom-layout/react-custom-layout が機能しない、何も描画されない、描画位置がずれる、またはサイズが正しくない
- DOM overlay の異常:react attribute(DOM コンテナーのマウント)が表示されない、位置が正しくない、canvas と同期しない
- React18 では正常、React19 では異常:custom-layout が空白になる、
older version of React element、React が二重に存在する、reconciler/hostConfig の互換性の問題 - React19 reconciler 関連の直接的なクラッシュ:
ReactCurrentOwner - VTable core の customLayout でデコードエラーが発生する:
decodeReactDom+type is not a function(rootContainer の type が想定と異なる) - 特定のインタラクションでのみ発生:スクロール/resize 後に消える、hover 時のみ表示される、固定列の切り替え後に位置がずれる
ワークフロー(順番に実行)
0) 再現/検証ワークフロー(ソースコードの調査時)
VTable のソースコード内で問題を調査・解決する場合は、次のワークフローを使用します:
問題を再現する:
/packages/vtable/examplesで問題に関連する demo を見つけるか、新しい demo を作成します。gantt の問題の場合は、/packages/vtable-gantt/examplesで該当する demo を見つけるか、新しい demo を作成します。プラグイン plugin の問題の場合は、/packages/vtable-plugins/demoで該当する demo を見つけるか、新しい demo を作成します。sheet スプレッドシートの問題の場合は、/packages/vtable-sheet/examplesで該当する demo を見つけるか、新しい demo を作成します。つまり、状況に応じて demo を作成するディレクトリを決定します。- 問題を再現するように demo の設定を変更します(例:
select.disableSelect、customMergeCellなどを設定) - demo サービスを起動します:
rushx demo(packages/vtableディレクトリ内で実行) - Chrome DevTools MCP を使用してブラウザーに接続し、問題が再現することを確認します
修正を検証する:
- ソースコードを変更した後、demo サービスが再読み込みされていることを確認します(Vite が自動的にホットアップデートします)
- 同じ demo を使用して、問題が解決したことを確認します
- 修正によって新たな問題が発生していないことを確認します(他のインタラクションへの影響、他の demo が正常に動作するかなど)
一般的なデバッグのヒント(DevTools MCP を利用):
- 設定を動的に変更して検証する:
table.options.select.disableSelect = ...やtable.theme.scrollStyleの変更などで設定を動的に注入できるため、コードを頻繁に変更したり、サービスを再起動したりせずに、さまざまな境界条件をテストできます。 - クロージャ/スコープの問題を調査する:VTable のイベントリスナー(
pointerleave、pointermoveなど)には、多くのクロージャ変数が含まれています。ロジックが想定どおりに実行されない場合は、MCP を利用してブレークポイントを設定したり、ログを出力したりして(プロトタイプチェーンのメソッドをオーバーライドするか、event listener を動的に追加)、クロージャ変数がundefinedまたは古い値になっていないか調査できます。 - Canvas イベントと Scenegraph の階層:
stageとtableGroupのイベントを区別します。Hover/Leave 関連の問題(スクロールバーや Tooltip が予期せず消えるなど)は、マウスが canvas の空白領域に移動したときにtableGroupのpointerleaveイベントが意図せず発生することが原因の場合があります。e.targetとe.relatedTargetに注意します。ノードがあるコンテナー内にあるかどうかを判定する際、target自体がstageの場合、e.target.isDescendantsOf(stage)はfalseを返します。正しい判定方法はtarget === stage || target?.isDescendantsOf?.(stage)です。
- 状態を取得する:
table.getSelectedCellRanges()を使用して、現在の選択範囲の状態を確認します。table.getCellRange(col, row)を使用して、セルの結合情報を確認します。
よくある落とし穴(NEVER)
- NEVER
stage.width/heightが 0 の場合、または親コンテナーの高さが未確定の場合に、scenegraph の詳細な調査を始めないでください。まずレイアウトとコンテナーの高さを修正します - NEVER 同じページに React/ReactDOM が二重に存在する疑いがある場合に、scenegraph の詳細を調査し続けないでください。まず alias/依存関係ツリーを修正し、同一ソースから読み込まれるようにします
- NEVER Fiber の汚染を検出した後(図形の
attributeにtag/child/sibling/return/memoizedProps/lanesなどが現れる場合)に、bounds の重ね合わせを続けないでください。reconciler HostConfig に戻って調査します(よくある箇所:commitUpdateの引数シグネチャ) - NEVER DOM/console だけを見て結論を出さないでください。描画内容の欠落やセルの位置ずれなど、canvas 関連の問題では、scenegraph ツリーと bounds を併せて比較し、検証する必要があります
- NEVER
componentGroupを無視しないでください。selection/tooltip/overlay など、「cell の問題」のように見える問題の多くは、実際には component/overlay レイヤーの問題です - NEVER マウスインタラクションの問題(Hover/Leave/Enter)を調査するとき、
e.target.isDescendantsOf(stage)がstage自体に対してtrueを返すと思い込まないでください。必ずtarget === stage || target?.isDescendantsOf?.(stage)を使用します - NEVER 内部 Group によるイベントの遮断を見落とさないでください。スクロールバーやハイライト状態が予期せず消える場合、
stageレイヤーだけで原因を探さないでください。多くの場合、内部のtableGroupまたは他の Group のpointerleave/pointeroutイベントがバブリングするか、予期しない非表示ロジックが実行されています - NEVER VTable 初期化時の変数が、クロージャ内で常に最新だと思い込まないでください。設定項目(
theme、optionsなど)は実行時にディープコピーまたは置き換えられる場合があるため、イベントリスナーなどのクロージャ内で外側のスコープ変数を直接分割代入したり使用したりすると、古い値を取得することがあります。問題が発生した場合は、MCP のevaluate_scriptを利用して、クロージャの実行時の実際の値を確認します - NEVER ツリー表示/遅延読み込み/折りたたみのシナリオで、
dataSource.getTableIndex(path)が返す-1を有効な表示行番号として扱い、ハイライト、focus、hover、selection、または更新のロジックに使用しないでください。-1は通常、「この path は現在表示されていない」ことを意味します。そのままrow = rawIndex + headerOffsetのように変換すると、ハイライトがヘッダーや別の表示セルに当たることがよくあります - NEVER 表示中の
row/colに依存するインタラクションロジック(customCellStyle arrangement、focus ハイライト、範囲枠など)で、「展開/折りたたみ/ソート/フィルター/データ更新」をまたいで古い座標をそのまま再利用しないでください。レイアウトが変わったら、まず古い arrangement/キャッシュをクリアし、最新の表示レイアウトに基づいて再計算する必要があります。そうしないと、古いrowが別のレコードを指し、「A を検索したのに B が黄色くなる」といった状態になります - NEVER ピボットテーブル(PivotTable)の角ヘッダーの状態(ソートアイコン、メニューなど)を調査するとき、
getCellAddressByHeaderPathsのような全体座標マッピング API に依存しないでください。行と列に同じ名前のディメンション(行と列の両方にCategoryディメンションが設定されているなど)が存在する場合、この種の API は最初に一致したセルの座標しか返しません。また、角ヘッダーセル自体のpivotInfoやdimensionKeyだけに依存して、単一箇所の状態を比較することも NEVER 避けてください。角ヘッダーは複数階層にネストされたディメンション(たとえばCategoryの下の第 2 階層であるSub-Category)を表す場合があります。正しい調査方法は、cornerSetting.titleOnDimensionとindicatorsAsColの設定を組み合わせて、角ヘッダーが行ディメンションか列ディメンションかを正確に特定し、col/row座標を使用してlayoutMap.rowDimensionKeysまたはlayoutMap.colDimensionKeysから完全な階層パス(path keys)を切り出して、対象のdimensions配列と長さおよび各階層を厳密に比較することです。
DevTools MCP 接続のトラブルシューティング
MCP エラー(例:DevToolsActivePort が見つからない、Network.enable timed out)が発生した場合は、まず snippets.md の 0) MCP 连接不上 Chrome に従って対処し、DevTools に接続できることを確認してから scenegraph の調査を続けてください。
1) table と scenegraph を取得する(必須)
目標:
- VTable インスタンス(ListTable/PivotTable)を取得する
table.scenegraph.stageが存在し、width/height が正常であることを確認する
必須: snippets.md の以下を読み込み、使用してください。
-
- ページ上の VTable インスタンスを検索する
-
- 各領域の group の childrenCount をすばやく確認する
2) 領域を特定する(必須)
現象に基づいて、調査対象の領域をすばやく特定します。
- 表ヘッダーの問題:
colHeaderGroup / rowHeaderGroup / cornerHeaderGroup - コンテンツ領域の問題:
bodyGroup / rightFrozenGroup / bottomFrozenGroup - DOM overlay / コンポーネントの問題:
componentGroup
scenegraph の領域構造を理解する必要がある場合は、必要に応じて以下を読み込みます。
3) 構造の問題:ツリーをエクスポートして cell を特定する(必要に応じて)
「エラーはないが、見た目がおかしい」場合:
- 対象領域の浅いツリーをエクスポートし、ノードが存在することを確認する
- col/row で対象の cell を探してから、深い階層までエクスポートする
必須: snippets.md の以下を読み込み、使用してください。
- 3) bodyGroup 内で col/row を指定して cell group を探す
-
- 任意の group のツリーをエクスポートする
4) 座標の問題:bounds を重ねて比較する(必要に応じて)
「ノードは存在するが、位置やサイズがおかしい」場合:
- 対象ノードの bounds を重ねて表示する
- 「シーンツリーの座標」と「画面上のピクセル」をスクリーンショットで比較する
必須: snippets.md の以下を読み込み、使用してください。
- 5) bounds を画面に重ねて表示する(スクリーンショットでの比較用)
5) クイックチェックリスト(必須)
- 「コンテナーの高さが 0/stage のサイズが 0/canvas が隠れている」といったレイアウトの問題を優先して除外する
- 領域の選択が正しいことを確認する(body vs frozen vs header)
- 対象ノードの
attribute.visible、透明度、clip/culling を確認する - bounds に異常(Infinity/0/負数/極端なオフセット)がある場合は、サイズ更新/座標系の変換/属性の誤った設定をまず疑う
- DOM overlay モードでは、container が正しいこと(
table.bodyDomContainer/table.headerDomContainer)、および container のサイズと配置が有効であることを確認する
6) React18/React19 の差異を調査する(まとめて対処)
「React18 では正常、React19 では異常」または「React19 で custom-layout が空白になる/ずれる」場合は、まず専用ガイドに従って切り分け(依存関係ツリー/React の二重読み込み/reconciler/HostConfig/DOM overlay)を行い、その後 scenegraph に戻って詳細を特定します。
必須: react18-react19.md を読み込み、最初から最後まで実行してください。