Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions docs/errors/DTK0013.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,10 @@ Authorize the browser. When an untrusted client connects, the dev-server termina
For automated setups (CI, shared machines), configure static trusted tokens instead — a client presenting one via the `devframe_auth_token` connection parameter is trusted without the interactive step:

```ts
import { DevTools } from '@vitejs/devtools'
// vite.config.ts
import { defineConfig } from 'vite'

export default defineConfig({
plugins: [
DevTools(),
],
devtools: {
enabled: true,
clientAuthTokens: ['your-trusted-token'],
Expand Down
41 changes: 13 additions & 28 deletions docs/guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,43 +70,33 @@ export default defineConfig({

### Customize the embedded UI

Vite adds the embedded dock automatically during `vite dev`. To customize it, add the `DevTools()` plugin manually. The examples keep the automatic integration enabled only for build to avoid mounting the dock twice.
Vite adds the embedded dock automatically during `vite dev`. Configure its UI through the core `devtools` option.

`embeddedVisibility` controls when the dock appears. The default `'normal'` shows it immediately. `'passive'` hides it until <kbd>Shift</kbd> + <kbd>Alt</kbd> + <kbd>D</kbd> (<kbd>⇧</kbd> <kbd>⌥</kbd> <kbd>D</kbd> on macOS) and remembers when it has been revealed. `'hidden'` uses the same shortcut without remembering the choice.

```ts [vite.config.ts] twoslash
import { DevTools } from '@vitejs/devtools'
import { defineConfig } from 'vite'

export default defineConfig({
plugins: [
DevTools({
embeddedVisibility: 'passive',
}),
],
devtools: {
apply: 'build',
apply: 'serve',
embeddedVisibility: 'passive',
},
})
Comment thread
webfansplz marked this conversation as resolved.
```

Use `dockPreferences` to set the initial dock layout. Users can still change these settings in DevTools.

```ts [vite.config.ts] twoslash
import { DevTools } from '@vitejs/devtools'
import { defineConfig } from 'vite'

export default defineConfig({
plugins: [
DevTools({
dockPreferences: {
defaultMode: 'edge',
defaultPosition: 'bottom',
},
}),
],
devtools: {
apply: 'build',
apply: 'serve',
dockPreferences: {
defaultMode: 'edge',
defaultPosition: 'bottom',
},
},
})
```
Expand Down Expand Up @@ -137,21 +127,16 @@ See [Client Script & Context](/kit/client-context#client-script-not-injected) fo
Set `build.withApp` to write the static DevTools files alongside the app build:

```ts [vite.config.ts] twoslash
import { DevTools } from '@vitejs/devtools'
import { defineConfig } from 'vite'

export default defineConfig({
plugins: [
DevTools({
build: {
withApp: true, // generate DevTools output during `vite build`
// outDir: 'custom-dir', // optional, defaults to Vite's build.outDir
},
}),
],
devtools: {
apply: 'build',
}
build: {
withApp: true, // generate DevTools output during `vite build`
// outDir: 'custom-dir', // optional, defaults to Vite's build.outDir
},
},
})
```

Expand Down
19 changes: 15 additions & 4 deletions packages/core/src/integration.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
import type { DevToolsConfig } from './node/config'
import {
DevToolsIntegration as _DevToolsIntegration,
runDevTools as _runDevTools,
} from './node/plugins/integration'

export interface DevToolsIntegrationConfig {
host: string
options: boolean | DevToolsConfig | undefined
}

export interface DevToolsIntegrationOptions {
config: unknown
command: 'serve' | 'build'
root: string
devtools: DevToolsIntegrationConfig
}

export function DevToolsIntegration(options: DevToolsIntegrationOptions): Promise<{ name: string }[]> {
return _DevToolsIntegration(options as Parameters<typeof _DevToolsIntegration>[0])
return _DevToolsIntegration(options)
}

export function runDevTools(builder: unknown): Promise<void> {
return _runDevTools(builder)
export function runDevTools(
builder: unknown,
devtools: DevToolsIntegrationConfig,
): Promise<void> {
return _runDevTools(builder, devtools)
}
17 changes: 12 additions & 5 deletions packages/core/src/node/__tests__/auth-handler.test.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
import type { ResolvedConfig } from 'vite'
import type { DevToolsConfig } from '../config'
import process from 'node:process'
import { describe, expect, it, vi } from 'vitest'
import { getAuthHandler } from '../auth-handler'
import { normalizeDevToolsConfig } from '../config'
import { createDevToolsContext } from '../context'
import '@vitejs/devtools-kit'

function createConfig(config?: Partial<DevToolsConfig>): ResolvedConfig {
function createConfig(): ResolvedConfig {
return {
root: process.cwd(),
command: 'serve',
plugins: [],
server: { port: 5173 },
devtools: config === undefined ? undefined : { config },
} as unknown as ResolvedConfig
}

describe('getAuthHandler banner', () => {
it('forwards a configured banner to the interactive auth handler', async () => {
const banner = vi.fn()
const ctx = await createDevToolsContext(createConfig({ banner }))
const ctx = await createDevToolsContext(
createConfig(),
undefined,
normalizeDevToolsConfig({ banner }, 'localhost'),
)

getAuthHandler(ctx).printBanner()

Expand All @@ -31,7 +34,11 @@ describe('getAuthHandler banner', () => {

it('falls back to the default stdout banner when unset', async () => {
const log = vi.spyOn(console, 'log').mockImplementation(() => {})
const ctx = await createDevToolsContext(createConfig())
const ctx = await createDevToolsContext(
createConfig(),
undefined,
normalizeDevToolsConfig(true, 'localhost'),
)

try {
getAuthHandler(ctx).printBanner()
Expand Down
35 changes: 28 additions & 7 deletions packages/core/src/node/__tests__/context-auth.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { ResolvedConfig } from 'vite'
import process from 'node:process'
import { afterEach, describe, expect, it } from 'vitest'
import { normalizeDevToolsConfig } from '../config'
import { createDevToolsContext } from '../context'
import '@vitejs/devtools-kit'

Expand All @@ -12,25 +13,37 @@ function createConfig(options: {
root: process.cwd(),
command: options.command ?? 'serve',
plugins: [],
devtools: options.clientAuth === undefined
? undefined
: { config: { clientAuth: options.clientAuth } },
} as unknown as ResolvedConfig
}

function createDevToolsConfig(clientAuth?: boolean) {
return normalizeDevToolsConfig(
clientAuth === undefined ? true : { clientAuth },
'localhost',
)
}

describe('createDevToolsContext auth registration', () => {
afterEach(() => {
delete process.env.VITE_DEVTOOLS_DISABLE_CLIENT_AUTH
})

it('registers the interactive-auth handshake when client auth is enabled', async () => {
const ctx = await createDevToolsContext(createConfig())
const ctx = await createDevToolsContext(
createConfig(),
undefined,
createDevToolsConfig(),
)

expect(ctx.rpc.definitions.has('anonymous:devframe:auth')).toBe(true)
})

it('skips the interactive-auth handshake in build mode (regression #539)', async () => {
const ctx = await createDevToolsContext(createConfig({ command: 'build' }))
const ctx = await createDevToolsContext(
createConfig({ command: 'build' }),
undefined,
createDevToolsConfig(),
)

// Left unregistered so devframe's `auth: false` auto-trust shim (armed
// by `createDevToolsHub`) can install its own noop handler and mark the
Expand All @@ -39,15 +52,23 @@ describe('createDevToolsContext auth registration', () => {
})

it('skips the interactive-auth handshake when `devtools.clientAuth` is false (regression #539)', async () => {
const ctx = await createDevToolsContext(createConfig({ clientAuth: false }))
const ctx = await createDevToolsContext(
createConfig({ clientAuth: false }),
undefined,
createDevToolsConfig(false),
)

expect(ctx.rpc.definitions.has('anonymous:devframe:auth')).toBe(false)
})

it('skips the interactive-auth handshake when VITE_DEVTOOLS_DISABLE_CLIENT_AUTH=true (regression #539)', async () => {
process.env.VITE_DEVTOOLS_DISABLE_CLIENT_AUTH = 'true'

const ctx = await createDevToolsContext(createConfig())
const ctx = await createDevToolsContext(
createConfig(),
undefined,
createDevToolsConfig(),
)

expect(ctx.rpc.definitions.has('anonymous:devframe:auth')).toBe(false)
})
Expand Down
Loading
Loading