diff --git a/docs/errors/DTK0035.md b/docs/errors/DTK0035.md new file mode 100644 index 00000000..c7b7a69e --- /dev/null +++ b/docs/errors/DTK0035.md @@ -0,0 +1,27 @@ +--- +outline: deep +--- +# DTK0035: Build Injection Requires Assets + +## Message +> build.injection requires build.withApp: true. + +## Cause +`build.injection` is enabled, but `build.withApp` is disabled. + +## Example +```ts +export default defineConfig({ + devtools: { + build: { + injection: true, + }, + }, +}) +``` + +## Fix +Set `devtools.build.withApp: true`. + +## Source +- [`packages/core/src/node/plugins/injection.ts`](https://github.com/vitejs/devtools/blob/main/packages/core/src/node/plugins/injection.ts) — `configResolved()` validates asset generation. diff --git a/docs/errors/index.md b/docs/errors/index.md index d1d6a4fc..fb0409b9 100644 --- a/docs/errors/index.md +++ b/docs/errors/index.md @@ -33,6 +33,7 @@ Emitted by `@vitejs/devtools` and `@vitejs/devtools-kit`. | [DTK0032](./DTK0032) | error | Dock Launch Error | | [DTK0033](./DTK0033) | warn | DevTools Mode Persist Failed | | [DTK0034](./DTK0034) | error | Duplicate DevTools Plugin | +| [DTK0035](./DTK0035) | error | Build Injection Requires Assets | | [DTK0050](./DTK0050) | error | Integration Install Failed | | [DTK0051](./DTK0051) | warn | Connection Meta Serve Failed | | [DTK0052](./DTK0052) | error | Launcher Process Exited Before Ready | diff --git a/docs/guide/index.md b/docs/guide/index.md index 14f5caa3..60d73b27 100644 --- a/docs/guide/index.md +++ b/docs/guide/index.md @@ -143,6 +143,21 @@ export default defineConfig({ Open `/__devtools/` for the full-page UI, or load `/__devtools/embedded.js` to embed the dock in the built app. +To show the dock in the built app, enable `build.injection`: + +```ts +export default defineConfig({ + devtools: { + build: { + withApp: true, + injection: true, + }, + }, +}) +``` + +Injection defaults to `false` and requires `build.withApp: true`. Ensure the DevTools assets are served under Vite's `base` when deployed. + ## What's next - **Explore the built-in tools** — inspect Vite development with [Vite DevTools](/vite/) and production builds with [DevTools for Rolldown](/rolldown/). diff --git a/packages/core/src/node/diagnostics.ts b/packages/core/src/node/diagnostics.ts index ea0ba52f..da5eee65 100644 --- a/packages/core/src/node/diagnostics.ts +++ b/packages/core/src/node/diagnostics.ts @@ -4,6 +4,10 @@ export const diagnostics = /* #__PURE__ */ defineDiagnostics({ docsBase: 'https://devtools.vite.dev/errors', reporters: [createConsoleReporter()], codes: { + DTK0035: { + why: 'build.injection requires build.withApp: true.', + fix: 'Set devtools.build.withApp to true.', + }, DTK0008: { why: 'Client authentication is disabled. Any browser can connect to the devtools and access your server and filesystem.', }, diff --git a/packages/core/src/node/plugin-options.ts b/packages/core/src/node/plugin-options.ts index df0f7a06..5714b87a 100644 --- a/packages/core/src/node/plugin-options.ts +++ b/packages/core/src/node/plugin-options.ts @@ -61,6 +61,12 @@ export interface DevToolsUserOptions { * @default false */ withApp?: boolean + /** + * Inject the dock into the built app. Requires `withApp: true`. + * Ensure the DevTools assets are served under Vite's `base` when deployed. + * @default false + */ + injection?: boolean /** Output directory relative to root. Defaults to Vite's `build.outDir`. */ outDir?: string } diff --git a/packages/core/src/node/plugins/index.ts b/packages/core/src/node/plugins/index.ts index b1b46f0c..1de6472f 100644 --- a/packages/core/src/node/plugins/index.ts +++ b/packages/core/src/node/plugins/index.ts @@ -60,7 +60,7 @@ export async function createDevToolsPlugins( const ui = { branding, embeddedVisibility, dockPreferences } const plugins = [ - DevToolsInjection(), + DevToolsInjection(build), DevToolsServer(ui, resolvedConfig, renderers), ] diff --git a/packages/core/src/node/plugins/injection.ts b/packages/core/src/node/plugins/injection.ts index 165d8885..da135a59 100644 --- a/packages/core/src/node/plugins/injection.ts +++ b/packages/core/src/node/plugins/injection.ts @@ -1,5 +1,7 @@ import type { Plugin } from 'vite' +import type { DevToolsUserOptions } from '../plugin-options' import { DEVTOOLS_MOUNT_PATH } from '@vitejs/devtools-kit/constants' +import { diagnostics } from '../diagnostics' /** * Inject the `@devframes/hub-ui` embedded bootstrap into the host app's HTML. @@ -20,14 +22,21 @@ import { DEVTOOLS_MOUNT_PATH } from '@vitejs/devtools-kit/constants' * keeps `embedded.js` out of Vite's graph entirely, so the browser * fetches it straight from the hub with its real URL intact. */ -export function DevToolsInjection(): Plugin { - const src = `${DEVTOOLS_MOUNT_PATH}embedded.js` +export function DevToolsInjection(build?: DevToolsUserOptions['build']): Plugin { + let src = `${DEVTOOLS_MOUNT_PATH}embedded.js` return { name: 'vite:devtools:injection', enforce: 'post', apply(_config, env) { - return env.command === 'serve' && !env.isSsrBuild + return !env.isSsrBuild && (env.command === 'serve' || build?.injection === true) + }, + configResolved(config) { + if (config.command === 'build') { + if (!build?.withApp) + throw diagnostics.DTK0035({}) + src = `${config.base.replace(/\/+$/, '')}${DEVTOOLS_MOUNT_PATH}embedded.js` + } }, transformIndexHtml: { order: 'pre',