@vitejs/devtools-kit 0.0.0-alpha.9 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.d.ts +2 -35
- package/dist/client.js +1734 -19
- package/dist/constants.d.ts +14 -0
- package/dist/constants.js +28 -0
- package/dist/events-B41U-zeg.d.ts +71 -0
- package/dist/index-WxzZW3L-.d.ts +679 -0
- package/dist/index.d.ts +9 -5
- package/dist/index.js +8 -15
- package/dist/shared-state-BFKKxNt1.d.ts +53 -0
- package/dist/utils/events.d.ts +9 -0
- package/dist/utils/events.js +40 -0
- package/dist/utils/nanoid.d.ts +4 -0
- package/dist/utils/nanoid.js +10 -0
- package/dist/utils/shared-state.d.ts +2 -0
- package/dist/utils/shared-state.js +36 -0
- package/package.json +19 -10
- package/skills/vite-devtools-kit/SKILL.md +436 -0
- package/skills/vite-devtools-kit/references/dock-entry-types.md +295 -0
- package/skills/vite-devtools-kit/references/logs-patterns.md +188 -0
- package/skills/vite-devtools-kit/references/project-structure.md +256 -0
- package/skills/vite-devtools-kit/references/rpc-patterns.md +185 -0
- package/skills/vite-devtools-kit/references/shared-state-patterns.md +292 -0
- package/dist/index-BtaHil_c.d.ts +0 -156
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
# Project Structure
|
|
2
|
+
|
|
3
|
+
Recommended file organization for DevTools integrations.
|
|
4
|
+
|
|
5
|
+
## Basic Structure
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
my-devtools-plugin/
|
|
9
|
+
├── src/
|
|
10
|
+
│ ├── node/
|
|
11
|
+
│ │ ├── index.ts # Plugin entry (exports main plugin)
|
|
12
|
+
│ │ ├── rpc/
|
|
13
|
+
│ │ │ ├── index.ts # RPC function exports
|
|
14
|
+
│ │ │ └── functions/ # Individual RPC functions
|
|
15
|
+
│ │ │ ├── get-modules.ts
|
|
16
|
+
│ │ │ └── get-stats.ts
|
|
17
|
+
│ │ └── utils.ts # Server-side utilities
|
|
18
|
+
│ ├── client/
|
|
19
|
+
│ │ ├── main.ts # Client app entry
|
|
20
|
+
│ │ ├── App.vue # Root component
|
|
21
|
+
│ │ └── composables/
|
|
22
|
+
│ │ └── rpc.ts # RPC composables
|
|
23
|
+
│ ├── types.ts # Type augmentations
|
|
24
|
+
│ └── shared/
|
|
25
|
+
│ └── constants.ts # Shared constants
|
|
26
|
+
├── dist/
|
|
27
|
+
│ ├── index.mjs # Node plugin bundle
|
|
28
|
+
│ └── client/ # Built client assets
|
|
29
|
+
├── package.json
|
|
30
|
+
└── tsconfig.json
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Package.json Configuration
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"name": "my-devtools-plugin",
|
|
38
|
+
"type": "module",
|
|
39
|
+
"exports": {
|
|
40
|
+
".": {
|
|
41
|
+
"import": "./dist/index.mjs",
|
|
42
|
+
"types": "./dist/index.d.ts"
|
|
43
|
+
},
|
|
44
|
+
"./devtools-action": {
|
|
45
|
+
"import": "./dist/devtools-action.mjs"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"files": ["dist"],
|
|
49
|
+
"scripts": {
|
|
50
|
+
"build": "tsdown src/node/index.ts && vite build src/client",
|
|
51
|
+
"dev": "vite src/client"
|
|
52
|
+
},
|
|
53
|
+
"dependencies": {},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@vitejs/devtools-kit": "^0.x.x",
|
|
56
|
+
"vite": "^6.x.x"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Plugin Entry (src/node/index.ts)
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
/// <reference types="@vitejs/devtools-kit" />
|
|
65
|
+
import type { Plugin } from 'vite'
|
|
66
|
+
import { fileURLToPath } from 'node:url'
|
|
67
|
+
import { rpcFunctions } from './rpc'
|
|
68
|
+
import '../types'
|
|
69
|
+
|
|
70
|
+
const clientDist = fileURLToPath(
|
|
71
|
+
new URL('../../dist/client', import.meta.url)
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
export default function myPlugin(): Plugin {
|
|
75
|
+
return {
|
|
76
|
+
name: 'my-plugin',
|
|
77
|
+
|
|
78
|
+
devtools: {
|
|
79
|
+
setup(ctx) {
|
|
80
|
+
// Register all RPC functions
|
|
81
|
+
for (const fn of rpcFunctions) {
|
|
82
|
+
ctx.rpc.register(fn)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Host static UI
|
|
86
|
+
ctx.views.hostStatic('/.my-plugin/', clientDist)
|
|
87
|
+
|
|
88
|
+
// Register dock entry
|
|
89
|
+
ctx.docks.register({
|
|
90
|
+
id: 'my-plugin',
|
|
91
|
+
title: 'My Plugin',
|
|
92
|
+
icon: 'ph:puzzle-piece-duotone',
|
|
93
|
+
type: 'iframe',
|
|
94
|
+
url: '/.my-plugin/',
|
|
95
|
+
})
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## RPC Index (src/node/rpc/index.ts)
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
import type { RpcDefinitionsToFunctions } from '@vitejs/devtools-kit'
|
|
106
|
+
import { getModules } from './functions/get-modules'
|
|
107
|
+
import { getStats } from './functions/get-stats'
|
|
108
|
+
import '@vitejs/devtools-kit'
|
|
109
|
+
|
|
110
|
+
export const rpcFunctions = [
|
|
111
|
+
getModules,
|
|
112
|
+
getStats,
|
|
113
|
+
] as const
|
|
114
|
+
|
|
115
|
+
export type ServerFunctions = RpcDefinitionsToFunctions<typeof rpcFunctions>
|
|
116
|
+
|
|
117
|
+
declare module '@vitejs/devtools-kit' {
|
|
118
|
+
export interface DevToolsRpcServerFunctions extends ServerFunctions {}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## RPC Function (src/node/rpc/functions/get-modules.ts)
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
import type { Module } from '../../../types'
|
|
126
|
+
import { defineRpcFunction } from '@vitejs/devtools-kit'
|
|
127
|
+
|
|
128
|
+
export const getModules = defineRpcFunction({
|
|
129
|
+
name: 'my-plugin:get-modules',
|
|
130
|
+
type: 'query',
|
|
131
|
+
setup: (ctx) => {
|
|
132
|
+
return {
|
|
133
|
+
handler: async (): Promise<Module[]> => {
|
|
134
|
+
// Access vite config, server, etc. from ctx
|
|
135
|
+
const root = ctx.viteConfig.root
|
|
136
|
+
return []
|
|
137
|
+
},
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
})
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Type Augmentations (src/types.ts)
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
import '@vitejs/devtools-kit'
|
|
147
|
+
|
|
148
|
+
export interface Module {
|
|
149
|
+
id: string
|
|
150
|
+
size: number
|
|
151
|
+
imports: string[]
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export interface MyPluginState {
|
|
155
|
+
modules: Module[]
|
|
156
|
+
selectedId: string | null
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
declare module '@vitejs/devtools-kit' {
|
|
160
|
+
interface DevToolsRpcSharedStates {
|
|
161
|
+
'my-plugin:state': MyPluginState
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Client Entry (src/client/main.ts)
|
|
167
|
+
|
|
168
|
+
```ts
|
|
169
|
+
import { createApp } from 'vue'
|
|
170
|
+
import App from './App.vue'
|
|
171
|
+
|
|
172
|
+
createApp(App).mount('#app')
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Client RPC Composable (src/client/composables/rpc.ts)
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
import { getDevToolsRpcClient } from '@vitejs/devtools-kit/client'
|
|
179
|
+
|
|
180
|
+
let clientPromise: Promise<Awaited<ReturnType<typeof getDevToolsRpcClient>>>
|
|
181
|
+
|
|
182
|
+
export function useRpc() {
|
|
183
|
+
if (!clientPromise) {
|
|
184
|
+
clientPromise = getDevToolsRpcClient()
|
|
185
|
+
}
|
|
186
|
+
return clientPromise
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Client App Component (src/client/App.vue)
|
|
191
|
+
|
|
192
|
+
```vue
|
|
193
|
+
<script setup lang="ts">
|
|
194
|
+
import type { Module } from '../types'
|
|
195
|
+
import { onMounted, shallowRef } from 'vue'
|
|
196
|
+
import { useRpc } from './composables/rpc'
|
|
197
|
+
|
|
198
|
+
const modules = shallowRef<Module[]>([])
|
|
199
|
+
const loading = shallowRef(true)
|
|
200
|
+
|
|
201
|
+
onMounted(async () => {
|
|
202
|
+
const rpc = await useRpc()
|
|
203
|
+
modules.value = await rpc.call('my-plugin:get-modules')
|
|
204
|
+
loading.value = false
|
|
205
|
+
})
|
|
206
|
+
</script>
|
|
207
|
+
|
|
208
|
+
<template>
|
|
209
|
+
<div class="p-4">
|
|
210
|
+
<h1 class="text-xl font-bold mb-4">
|
|
211
|
+
My Plugin
|
|
212
|
+
</h1>
|
|
213
|
+
<div v-if="loading">
|
|
214
|
+
Loading...
|
|
215
|
+
</div>
|
|
216
|
+
<ul v-else>
|
|
217
|
+
<li v-for="mod in modules" :key="mod.id">
|
|
218
|
+
{{ mod.id }} ({{ mod.size }} bytes)
|
|
219
|
+
</li>
|
|
220
|
+
</ul>
|
|
221
|
+
</div>
|
|
222
|
+
</template>
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Vite Config for Client (src/client/vite.config.ts)
|
|
226
|
+
|
|
227
|
+
```ts
|
|
228
|
+
import vue from '@vitejs/plugin-vue'
|
|
229
|
+
import { defineConfig } from 'vite'
|
|
230
|
+
|
|
231
|
+
export default defineConfig({
|
|
232
|
+
plugins: [vue()],
|
|
233
|
+
build: {
|
|
234
|
+
outDir: '../../dist/client',
|
|
235
|
+
emptyOutDir: true,
|
|
236
|
+
},
|
|
237
|
+
})
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Real-World References
|
|
241
|
+
|
|
242
|
+
### In-Repo Examples
|
|
243
|
+
|
|
244
|
+
Reference these for code structure and patterns when building new integrations:
|
|
245
|
+
|
|
246
|
+
- [`examples/plugin-a11y-checker`](https://github.com/vitejs/devtools/tree/main/examples/plugin-a11y-checker) — Action entry, client-side audits, logs with element positions, log handle updates
|
|
247
|
+
- [`examples/plugin-file-explorer`](https://github.com/vitejs/devtools/tree/main/examples/plugin-file-explorer) — Iframe entry, multiple RPC types, hosted UI panel, RPC dump for static builds
|
|
248
|
+
|
|
249
|
+
### Internal Packages
|
|
250
|
+
|
|
251
|
+
See [packages/vite](https://github.com/vitejs/devtools/tree/main/packages/vite) for a complete implementation with:
|
|
252
|
+
|
|
253
|
+
- Multiple RPC functions organized by feature
|
|
254
|
+
- Nuxt-based client UI
|
|
255
|
+
- Complex data visualization
|
|
256
|
+
- Build session management
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# RPC Patterns
|
|
2
|
+
|
|
3
|
+
Advanced patterns for server-client communication in DevTools integrations.
|
|
4
|
+
|
|
5
|
+
## Function Types
|
|
6
|
+
|
|
7
|
+
| Type | Caching | Use Case |
|
|
8
|
+
|------|---------|----------|
|
|
9
|
+
| `query` | Can be cached | Read operations, data fetching |
|
|
10
|
+
| `action` | Never cached | Mutations, side effects |
|
|
11
|
+
| `static` | Cached indefinitely | Constants, configuration |
|
|
12
|
+
|
|
13
|
+
## Type-Safe RPC Setup
|
|
14
|
+
|
|
15
|
+
### Step 1: Define Types
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
// src/types.ts
|
|
19
|
+
import '@vitejs/devtools-kit'
|
|
20
|
+
|
|
21
|
+
interface Module {
|
|
22
|
+
id: string
|
|
23
|
+
size: number
|
|
24
|
+
imports: string[]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
declare module '@vitejs/devtools-kit' {
|
|
28
|
+
interface DevToolsRpcServerFunctions {
|
|
29
|
+
'my-plugin:list-modules': () => Promise<Module[]>
|
|
30
|
+
'my-plugin:get-module': (id: string) => Promise<Module | null>
|
|
31
|
+
'my-plugin:analyze': (options: { deep: boolean }) => Promise<void>
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface DevToolsRpcClientFunctions {
|
|
35
|
+
'my-plugin:highlight': (selector: string) => void
|
|
36
|
+
'my-plugin:refresh': () => void
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Step 2: Import Types File
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
// src/node/plugin.ts
|
|
45
|
+
import '../types' // Side-effect import for type augmentation
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Step 3: Register Functions
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import { defineRpcFunction } from '@vitejs/devtools-kit'
|
|
52
|
+
|
|
53
|
+
const listModules = defineRpcFunction({
|
|
54
|
+
name: 'my-plugin:list-modules',
|
|
55
|
+
type: 'query',
|
|
56
|
+
setup: () => ({
|
|
57
|
+
handler: async (): Promise<Module[]> => {
|
|
58
|
+
return Array.from(moduleMap.values())
|
|
59
|
+
},
|
|
60
|
+
}),
|
|
61
|
+
})
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Context Access in Setup
|
|
65
|
+
|
|
66
|
+
The `setup` function receives the full `DevToolsNodeContext`:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
defineRpcFunction({
|
|
70
|
+
name: 'my-plugin:get-config',
|
|
71
|
+
type: 'static',
|
|
72
|
+
setup: (ctx) => {
|
|
73
|
+
// Access at setup time (runs once)
|
|
74
|
+
const root = ctx.viteConfig.root
|
|
75
|
+
const isDev = ctx.mode === 'dev'
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
handler: async () => ({
|
|
79
|
+
root,
|
|
80
|
+
isDev,
|
|
81
|
+
plugins: ctx.viteConfig.plugins.map(p => p.name),
|
|
82
|
+
}),
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
})
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Broadcasting Patterns
|
|
89
|
+
|
|
90
|
+
### Basic Broadcast
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
// Notify all clients
|
|
94
|
+
ctx.rpc.broadcast({
|
|
95
|
+
method: 'my-plugin:refresh',
|
|
96
|
+
args: [],
|
|
97
|
+
})
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Broadcast with Data
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
ctx.viteServer?.watcher.on('change', (file) => {
|
|
104
|
+
ctx.rpc.broadcast({
|
|
105
|
+
method: 'my-plugin:file-changed',
|
|
106
|
+
args: [{ path: file, timestamp: Date.now() }],
|
|
107
|
+
})
|
|
108
|
+
})
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Optional Broadcast
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
// Won't error if no clients have registered the function
|
|
115
|
+
ctx.rpc.broadcast({
|
|
116
|
+
method: 'my-plugin:optional-update',
|
|
117
|
+
args: [data],
|
|
118
|
+
optional: true,
|
|
119
|
+
})
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Client Function Registration
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
// Client-side (action/renderer script)
|
|
126
|
+
export default function setup(ctx: DevToolsClientScriptContext) {
|
|
127
|
+
ctx.current.rpc.client.register({
|
|
128
|
+
name: 'my-plugin:highlight',
|
|
129
|
+
type: 'action',
|
|
130
|
+
handler: (selector: string) => {
|
|
131
|
+
const el = document.querySelector(selector)
|
|
132
|
+
if (el) {
|
|
133
|
+
el.style.outline = '3px solid red'
|
|
134
|
+
setTimeout(() => {
|
|
135
|
+
el.style.outline = ''
|
|
136
|
+
}, 2000)
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
})
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Collecting RPC Functions
|
|
144
|
+
|
|
145
|
+
Organize RPC functions in a registry pattern:
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
import { analyzeBundle } from './functions/analyze-bundle'
|
|
149
|
+
// src/node/rpc/index.ts
|
|
150
|
+
import { getModules } from './functions/get-modules'
|
|
151
|
+
import { getStats } from './functions/get-stats'
|
|
152
|
+
|
|
153
|
+
export const rpcFunctions = [
|
|
154
|
+
getModules,
|
|
155
|
+
getStats,
|
|
156
|
+
analyzeBundle,
|
|
157
|
+
] as const
|
|
158
|
+
|
|
159
|
+
// Register all in setup
|
|
160
|
+
for (const fn of rpcFunctions) {
|
|
161
|
+
ctx.rpc.register(fn)
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Type Extraction Utilities
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
import type {
|
|
169
|
+
RpcDefinitionsFilter,
|
|
170
|
+
RpcDefinitionsToFunctions,
|
|
171
|
+
} from '@vitejs/devtools-kit'
|
|
172
|
+
|
|
173
|
+
// Extract all function types
|
|
174
|
+
export type ServerFunctions = RpcDefinitionsToFunctions<typeof rpcFunctions>
|
|
175
|
+
|
|
176
|
+
// Extract only static functions
|
|
177
|
+
export type StaticFunctions = RpcDefinitionsToFunctions<
|
|
178
|
+
RpcDefinitionsFilter<typeof rpcFunctions, 'static'>
|
|
179
|
+
>
|
|
180
|
+
|
|
181
|
+
// Augment the global interface
|
|
182
|
+
declare module '@vitejs/devtools-kit' {
|
|
183
|
+
export interface DevToolsRpcServerFunctions extends ServerFunctions {}
|
|
184
|
+
}
|
|
185
|
+
```
|