Skip to content

Commit aef55c4

Browse files
committed
feat: new self-inspect plugin
1 parent b30faf0 commit aef55c4

30 files changed

+953
-2
lines changed

alias.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export const alias = {
1919
'@vitejs/devtools-kit/utils/shared-state': r('kit/src/utils/shared-state.ts'),
2020
'@vitejs/devtools-kit': r('kit/src/index.ts'),
2121
'@vitejs/devtools-rolldown': r('rolldown/src/index.ts'),
22+
'@vitejs/devtools-self-inspect': r('self-inspect/src/index.ts'),
2223
'@vitejs/devtools/client/inject': r('core/src/client/inject/index.ts'),
2324
'@vitejs/devtools/client/webcomponents': r('core/src/client/webcomponents/index.ts'),
2425
'@vitejs/devtools': r('core/src/index.ts'),

docs/kit/devtools-plugin.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,28 @@ export default function myAnalyzerPlugin(): Plugin {
210210
}
211211
```
212212

213+
## Debugging with Self Inspect
214+
215+
When developing or debugging a DevTools plugin, you can install `@vitejs/devtools-self-inspect` to get a live view of all registered RPC functions, dock entries, client scripts, and DevTools-enabled plugins:
216+
217+
```bash
218+
pnpm add -D @vitejs/devtools-self-inspect
219+
```
220+
221+
```ts [vite.config.ts]
222+
import { DevToolsSelfInspect } from '@vitejs/devtools-self-inspect'
223+
224+
export default defineConfig({
225+
plugins: [
226+
DevTools(),
227+
DevToolsSelfInspect(),
228+
// ...your plugins
229+
],
230+
})
231+
```
232+
233+
This adds a "Self Inspect" panel to DevTools that shows the internal state of the DevTools system — helpful for verifying that your plugin's RPC functions, docks, and client scripts are registered correctly.
234+
213235
## Next Steps
214236

215237
- **[Dock System](./dock-system)** - Learn about different dock entry types (iframe, action, custom renderer)

packages/core/playground/vite.config.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ import VueRouter from 'unplugin-vue-router/vite'
55
import { defineConfig } from 'vite'
66
import Tracer from 'vite-plugin-vue-tracer'
77
import { alias } from '../../../alias'
8+
import { DevTools } from '../../core/src'
9+
import { buildCSS } from '../../core/src/client/webcomponents/scripts/build-css'
810
// eslint-disable-next-line ts/ban-ts-comment
911
// @ts-ignore ignore the type error
1012
import { DevToolsRolldownUI } from '../../rolldown/src/node'
11-
import { DevTools } from '../src'
12-
import { buildCSS } from '../src/client/webcomponents/scripts/build-css'
13+
import { DevToolsSelfInspect } from '../../self-inspect/src/node'
1314

1415
declare module '@vitejs/devtools-kit' {
1516
interface DevToolsRpcSharedStates {
@@ -29,6 +30,7 @@ export default defineConfig({
2930
plugins: [
3031
VueRouter(),
3132
Vue(),
33+
DevToolsSelfInspect(),
3234
{
3335
name: 'build-css',
3436
handleHotUpdate({ file }) {

packages/self-inspect/README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# @vitejs/devtools-self-inspect
2+
3+
A Vite DevTools plugin for inspecting the DevTools itself. Useful when developing or debugging DevTools plugins built with `@vitejs/devtools-kit`.
4+
5+
## Features
6+
7+
- List all registered RPC functions with their metadata (type, schema, cacheability, etc.)
8+
- List all registered dock entries
9+
- List all registered client scripts
10+
- List all Vite plugins with DevTools support and their capabilities
11+
12+
## Installation
13+
14+
```bash
15+
pnpm add -D @vitejs/devtools-self-inspect
16+
```
17+
18+
## Usage
19+
20+
Add the plugin to your Vite config:
21+
22+
```ts
23+
import DevTools from '@vitejs/devtools'
24+
import { DevToolsSelfInspect } from '@vitejs/devtools-self-inspect'
25+
// vite.config.ts
26+
import { defineConfig } from 'vite'
27+
28+
export default defineConfig({
29+
plugins: [
30+
DevTools(),
31+
DevToolsSelfInspect(),
32+
],
33+
})
34+
```
35+
36+
A "Self Inspect" panel will appear in the DevTools dock, giving you a live view of the registered RPC functions, docks, client scripts, and DevTools-enabled plugins.

packages/self-inspect/package.json

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"name": "@vitejs/devtools-self-inspect",
3+
"type": "module",
4+
"version": "0.0.0-alpha.34",
5+
"description": "DevTools for inspecting the DevTools itself",
6+
"author": "VoidZero Inc.",
7+
"license": "MIT",
8+
"homepage": "https://github.com/vitejs/devtools#readme",
9+
"repository": {
10+
"directory": "packages/self-inspect",
11+
"type": "git",
12+
"url": "git+https://github.com/vitejs/devtools.git"
13+
},
14+
"bugs": "https://github.com/vitejs/devtools/issues",
15+
"keywords": [
16+
"devtools",
17+
"self-inspect"
18+
],
19+
"sideEffects": false,
20+
"exports": {
21+
".": "./dist/index.mjs",
22+
"./dirs": "./dist/dirs.mjs",
23+
"./package.json": "./package.json"
24+
},
25+
"types": "./dist/index.d.mts",
26+
"files": [
27+
"dist"
28+
],
29+
"scripts": {
30+
"build": "pnpm dev:prepare && nuxi build src && tsdown",
31+
"dev": "nuxi dev src",
32+
"dev:prepare": "nuxi prepare src",
33+
"prepack": "pnpm build"
34+
},
35+
"dependencies": {
36+
"@vitejs/devtools-kit": "workspace:*",
37+
"@vitejs/devtools-rpc": "workspace:*",
38+
"birpc": "catalog:deps",
39+
"pathe": "catalog:deps"
40+
},
41+
"devDependencies": {
42+
"@unocss/nuxt": "catalog:build",
43+
"@vueuse/core": "catalog:frontend",
44+
"@vueuse/nuxt": "catalog:build",
45+
"structured-clone-es": "catalog:deps",
46+
"tsdown": "catalog:build",
47+
"unocss": "catalog:build",
48+
"vite-hot-client": "catalog:frontend"
49+
}
50+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<script setup lang="ts">
2+
import { useHead } from '#app/composables/head'
3+
4+
import { connect, connectionState } from './composables/rpc'
5+
import './styles/global.css'
6+
import '@vitejs/devtools-ui/composables/dark'
7+
8+
useHead({
9+
title: 'DevTools Self Inspect',
10+
})
11+
12+
connect()
13+
</script>
14+
15+
<template>
16+
<div v-if="connectionState.error" text-red p4>
17+
{{ connectionState.error }}
18+
</div>
19+
<VisualLoading
20+
v-else-if="!connectionState.connected"
21+
text="Connecting..."
22+
/>
23+
<div v-else h-vh>
24+
<NuxtPage />
25+
</div>
26+
</template>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<script setup lang="ts">
2+
import type { ClientScriptInfo } from '~~/node/rpc/functions/get-client-scripts'
3+
4+
defineProps<{
5+
scripts: ClientScriptInfo[]
6+
}>()
7+
</script>
8+
9+
<template>
10+
<div v-if="scripts.length === 0" flex="~ items-center justify-center" py8 op50>
11+
No client scripts registered.
12+
</div>
13+
<table v-else w-full text-sm>
14+
<thead>
15+
<tr border="b base" text-left>
16+
<th px2 py1.5 font-medium op60>
17+
Dock ID
18+
</th>
19+
<th px2 py1.5 font-medium op60>
20+
Dock Title
21+
</th>
22+
<th px2 py1.5 font-medium op60>
23+
Dock Type
24+
</th>
25+
<th px2 py1.5 font-medium op60>
26+
Import From
27+
</th>
28+
<th px2 py1.5 font-medium op60>
29+
Import Name
30+
</th>
31+
</tr>
32+
</thead>
33+
<tbody>
34+
<tr v-for="script in scripts" :key="script.dockId" border="b base" hover:bg-active>
35+
<td px2 py1.5 font-mono text-xs>
36+
{{ script.dockId }}
37+
</td>
38+
<td px2 py1.5>
39+
{{ script.dockTitle }}
40+
</td>
41+
<td px2 py1.5>
42+
<DisplayBadge :text="script.dockType" />
43+
</td>
44+
<td px2 py1.5 font-mono text-xs max-w-60 truncate>
45+
{{ script.script.importFrom }}
46+
</td>
47+
<td px2 py1.5 font-mono text-xs>
48+
{{ script.script.importName ?? 'default' }}
49+
</td>
50+
</tr>
51+
</tbody>
52+
</table>
53+
</template>
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<script setup lang="ts">
2+
import type { DevtoolsPluginInfo } from '~~/node/rpc/functions/get-devtools-plugins'
3+
import { computed, ref } from 'vue'
4+
5+
const props = defineProps<{
6+
plugins: DevtoolsPluginInfo[]
7+
}>()
8+
9+
const showAll = ref(false)
10+
11+
const filtered = computed(() => {
12+
if (showAll.value)
13+
return props.plugins
14+
return props.plugins.filter(p => p.hasDevtools)
15+
})
16+
</script>
17+
18+
<template>
19+
<div flex="~ col gap-3">
20+
<div flex="~ items-center gap-2">
21+
<label flex="~ items-center gap-1.5" text-sm op60 cursor-pointer select-none>
22+
<input v-model="showAll" type="checkbox">
23+
Show all Vite plugins ({{ plugins.length }} total)
24+
</label>
25+
</div>
26+
<table w-full text-sm>
27+
<thead>
28+
<tr border="b base" text-left>
29+
<th px2 py1.5 font-medium op60>
30+
Plugin Name
31+
</th>
32+
<th px2 py1.5 font-medium op60 text-center>
33+
DevTools
34+
</th>
35+
<th px2 py1.5 font-medium op60 text-center>
36+
Setup
37+
</th>
38+
<th px2 py1.5 font-medium op60>
39+
Capabilities
40+
</th>
41+
</tr>
42+
</thead>
43+
<tbody>
44+
<tr v-for="plugin in filtered" :key="plugin.name" border="b base" hover:bg-active>
45+
<td px2 py1.5 font-mono text-xs>
46+
{{ plugin.name }}
47+
</td>
48+
<td px2 py1.5 text-center>
49+
<span v-if="plugin.hasDevtools" i-ph-check text-green />
50+
<span v-else op20>-</span>
51+
</td>
52+
<td px2 py1.5 text-center>
53+
<span v-if="plugin.hasSetup" i-ph-check text-green />
54+
<span v-else op20>-</span>
55+
</td>
56+
<td px2 py1.5 text-xs>
57+
<span v-if="plugin.capabilities" font-mono op60>
58+
{{ JSON.stringify(plugin.capabilities) }}
59+
</span>
60+
<span v-else op20>-</span>
61+
</td>
62+
</tr>
63+
</tbody>
64+
</table>
65+
</div>
66+
</template>
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<script setup lang="ts">
2+
import type { DevToolsDockEntry } from '@vitejs/devtools-kit'
3+
4+
defineProps<{
5+
docks: DevToolsDockEntry[]
6+
}>()
7+
</script>
8+
9+
<template>
10+
<table w-full text-sm>
11+
<thead>
12+
<tr border="b base" text-left>
13+
<th px2 py1.5 font-medium op60>
14+
ID
15+
</th>
16+
<th px2 py1.5 font-medium op60>
17+
Title
18+
</th>
19+
<th px2 py1.5 font-medium op60>
20+
Type
21+
</th>
22+
<th px2 py1.5 font-medium op60>
23+
Category
24+
</th>
25+
<th px2 py1.5 font-medium op60 text-center>
26+
Hidden
27+
</th>
28+
</tr>
29+
</thead>
30+
<tbody>
31+
<tr v-for="dock in docks" :key="dock.id" border="b base" hover:bg-active>
32+
<td px2 py1.5 font-mono text-xs>
33+
{{ dock.id }}
34+
</td>
35+
<td px2 py1.5>
36+
{{ dock.title }}
37+
</td>
38+
<td px2 py1.5>
39+
<DisplayBadge :text="dock.type" />
40+
</td>
41+
<td px2 py1.5>
42+
<span v-if="dock.category" text-xs op60>{{ dock.category }}</span>
43+
<span v-else op20>-</span>
44+
</td>
45+
<td px2 py1.5 text-center>
46+
<span v-if="dock.isHidden" i-ph-eye-slash op40 />
47+
<span v-else op20>-</span>
48+
</td>
49+
</tr>
50+
</tbody>
51+
</table>
52+
</template>

0 commit comments

Comments
 (0)