From 3e9c398625a014f630d90f5fbefe5621be01a242 Mon Sep 17 00:00:00 2001 From: arlo Date: Thu, 23 Apr 2026 18:19:47 +0800 Subject: [PATCH 1/3] feat: init --- packages/core/package.json | 1 + packages/core/src/integration.ts | 2 + packages/core/src/node/config.ts | 50 +++++++++++++++++ packages/core/src/node/plugins/integration.ts | 56 +++++++++++++++++++ packages/core/tsdown.config.ts | 1 + 5 files changed, 110 insertions(+) create mode 100644 packages/core/src/integration.ts create mode 100644 packages/core/src/node/plugins/integration.ts diff --git a/packages/core/package.json b/packages/core/package.json index 17b0e988..83563ad1 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -27,6 +27,7 @@ "./client/webcomponents": "./dist/client/webcomponents.js", "./config": "./dist/config.js", "./dirs": "./dist/dirs.js", + "./integration": "./dist/integration.js", "./internal": "./dist/internal.js", "./package.json": "./package.json" }, diff --git a/packages/core/src/integration.ts b/packages/core/src/integration.ts new file mode 100644 index 00000000..5bdb7045 --- /dev/null +++ b/packages/core/src/integration.ts @@ -0,0 +1,2 @@ +export { DevToolsIntegration } from './node/plugins/integration' +export type { DevToolsIntegrationOptions } from './node/plugins/integration' diff --git a/packages/core/src/node/config.ts b/packages/core/src/node/config.ts index ea99b61a..030f5ae7 100644 --- a/packages/core/src/node/config.ts +++ b/packages/core/src/node/config.ts @@ -27,6 +27,15 @@ export interface ResolvedDevToolsConfig { enabled: boolean } +function normalizeHostname(host: string | boolean | undefined): string { + return host === undefined || host === false || host === true + ? 'localhost' + : host +} + +/** + * @deprecated Use `resolveDevToolsConfig()` instead. + */ export function normalizeDevToolsConfig( config: DevToolsConfig | boolean | undefined, host: string, @@ -41,3 +50,44 @@ export function normalizeDevToolsConfig( }, } } + +export function resolveDevToolsConfig( + config: DevToolsConfig | boolean | undefined, + host: string | boolean | undefined, + resolvedConfig?: ResolvedDevToolsConfig, +): ResolvedDevToolsConfig { + if (config === undefined && resolvedConfig) { + return resolvedConfig + } + + const normalizedHost = normalizeHostname(host) + + if (!isObject(config)) { + return { + enabled: config === true, + config: { + clientAuth: true, + clientAuthTokens: [], + host: normalizedHost, + }, + } + } + + const { + enabled, + clientAuth = true, + clientAuthTokens = [], + host: resolvedHost = normalizedHost, + ...normalizedConfig + } = config + + return { + enabled, + config: { + ...normalizedConfig, + clientAuth, + clientAuthTokens, + host: resolvedHost, + }, + } +} diff --git a/packages/core/src/node/plugins/integration.ts b/packages/core/src/node/plugins/integration.ts new file mode 100644 index 00000000..5d7062ea --- /dev/null +++ b/packages/core/src/node/plugins/integration.ts @@ -0,0 +1,56 @@ +import type { Plugin, ResolvedConfig } from 'vite' +import type { DevToolsConfig, ResolvedDevToolsConfig } from '../config' +import { resolveDevToolsConfig } from '../config' + +export interface DevToolsIntegrationOptions { + devtools?: DevToolsConfig | boolean + host?: string | boolean +} + +export function DevToolsIntegration(options: DevToolsIntegrationOptions = {}): Plugin { + let resolvedConfig: ResolvedConfig | undefined + let normalizedDevToolsConfig: ResolvedDevToolsConfig | undefined + + return { + name: 'vite:devtools:integration', + apply: 'build', + configResolved: { + order: 'post', + handler(config) { + resolvedConfig = config + normalizedDevToolsConfig = resolveDevToolsConfig( + options.devtools, + options.host ?? config.server.host, + config.devtools, + ) + + if (!normalizedDevToolsConfig.enabled) { + return + } + config.build.rolldownOptions ??= {} + config.build.rolldownOptions.devtools ??= {} + }, + }, + buildApp: { + order: 'post', + async handler(builder) { + const config = resolvedConfig ?? builder.config + + if (!normalizedDevToolsConfig?.enabled) { + return + } + + try { + const { start } = await import('@vitejs/devtools/cli-commands') + await start(normalizedDevToolsConfig.config) + } + catch (error: any) { + config.logger.error( + `Failed to run Vite DevTools: ${error?.message || error?.stack || error}`, + { error }, + ) + } + }, + }, + } +} diff --git a/packages/core/tsdown.config.ts b/packages/core/tsdown.config.ts index 272319e1..7c6e9fd7 100644 --- a/packages/core/tsdown.config.ts +++ b/packages/core/tsdown.config.ts @@ -53,6 +53,7 @@ export default defineConfig({ tsconfig: '../../tsconfig.base.json', entry: { 'index': 'src/index.ts', + 'integration': 'src/integration.ts', 'internal': 'src/internal.ts', 'dirs': 'src/dirs.ts', 'cli': 'src/node/cli.ts', From 0cacb1f9b5dea1780be9a9d8ae1e3f44f7e24995 Mon Sep 17 00:00:00 2001 From: arlo Date: Thu, 23 Apr 2026 22:40:49 +0800 Subject: [PATCH 2/3] chore: update --- packages/core/src/integration.ts | 2 +- packages/core/src/node/config.ts | 54 +------------ packages/core/src/node/plugins/integration.ts | 79 +++++++++---------- test/exports/@vitejs/devtools.yaml | 3 + 4 files changed, 47 insertions(+), 91 deletions(-) diff --git a/packages/core/src/integration.ts b/packages/core/src/integration.ts index 5bdb7045..fe8832e6 100644 --- a/packages/core/src/integration.ts +++ b/packages/core/src/integration.ts @@ -1,2 +1,2 @@ -export { DevToolsIntegration } from './node/plugins/integration' +export { DevToolsIntegration, runDevTools } from './node/plugins/integration' export type { DevToolsIntegrationOptions } from './node/plugins/integration' diff --git a/packages/core/src/node/config.ts b/packages/core/src/node/config.ts index 030f5ae7..8f982bfd 100644 --- a/packages/core/src/node/config.ts +++ b/packages/core/src/node/config.ts @@ -3,6 +3,10 @@ import { isObject } from './utils' export interface DevToolsConfig extends Partial { enabled: boolean + /** + * Vite environments to enable DevTools for. Defaults to all environments. + */ + environments?: string[] /** * Disable client authentication. * @@ -27,15 +31,6 @@ export interface ResolvedDevToolsConfig { enabled: boolean } -function normalizeHostname(host: string | boolean | undefined): string { - return host === undefined || host === false || host === true - ? 'localhost' - : host -} - -/** - * @deprecated Use `resolveDevToolsConfig()` instead. - */ export function normalizeDevToolsConfig( config: DevToolsConfig | boolean | undefined, host: string, @@ -50,44 +45,3 @@ export function normalizeDevToolsConfig( }, } } - -export function resolveDevToolsConfig( - config: DevToolsConfig | boolean | undefined, - host: string | boolean | undefined, - resolvedConfig?: ResolvedDevToolsConfig, -): ResolvedDevToolsConfig { - if (config === undefined && resolvedConfig) { - return resolvedConfig - } - - const normalizedHost = normalizeHostname(host) - - if (!isObject(config)) { - return { - enabled: config === true, - config: { - clientAuth: true, - clientAuthTokens: [], - host: normalizedHost, - }, - } - } - - const { - enabled, - clientAuth = true, - clientAuthTokens = [], - host: resolvedHost = normalizedHost, - ...normalizedConfig - } = config - - return { - enabled, - config: { - ...normalizedConfig, - clientAuth, - clientAuthTokens, - host: resolvedHost, - }, - } -} diff --git a/packages/core/src/node/plugins/integration.ts b/packages/core/src/node/plugins/integration.ts index 5d7062ea..a578091d 100644 --- a/packages/core/src/node/plugins/integration.ts +++ b/packages/core/src/node/plugins/integration.ts @@ -1,54 +1,53 @@ -import type { Plugin, ResolvedConfig } from 'vite' -import type { DevToolsConfig, ResolvedDevToolsConfig } from '../config' -import { resolveDevToolsConfig } from '../config' +import type { Plugin, ResolvedConfig, ViteBuilder } from 'vite' +import type { ResolvedDevToolsConfig } from '../config' + +type DevToolsEnvironment = ResolvedConfig['environments'][string] export interface DevToolsIntegrationOptions { - devtools?: DevToolsConfig | boolean - host?: string | boolean + config: ResolvedConfig } -export function DevToolsIntegration(options: DevToolsIntegrationOptions = {}): Plugin { - let resolvedConfig: ResolvedConfig | undefined - let normalizedDevToolsConfig: ResolvedDevToolsConfig | undefined +function getDevToolsEnvironments(config: ResolvedConfig): DevToolsEnvironment[] { + const devToolsConfig = config.devtools as ResolvedDevToolsConfig + const environmentNames = devToolsConfig.config.environments ?? Object.keys(config.environments) + const environments: DevToolsEnvironment[] = [] + + for (const environmentName of environmentNames) { + const environment = config.environments[environmentName] + if (environment) { + environments.push(environment) + } + } + + return environments +} +export async function runDevTools(builder: unknown) { + const config = (builder as ViteBuilder).config + for (const _environment of getDevToolsEnvironments(config)) { + try { + const { start } = await import('@vitejs/devtools/cli-commands') + await start(config.devtools.config) + } + catch (error: any) { + config.logger.error( + `Failed to run Vite DevTools: ${error?.message || error?.stack || error}`, + { error }, + ) + } + } +} + +export function DevToolsIntegration(_options: DevToolsIntegrationOptions): Plugin { return { name: 'vite:devtools:integration', apply: 'build', configResolved: { order: 'post', handler(config) { - resolvedConfig = config - normalizedDevToolsConfig = resolveDevToolsConfig( - options.devtools, - options.host ?? config.server.host, - config.devtools, - ) - - if (!normalizedDevToolsConfig.enabled) { - return - } - config.build.rolldownOptions ??= {} - config.build.rolldownOptions.devtools ??= {} - }, - }, - buildApp: { - order: 'post', - async handler(builder) { - const config = resolvedConfig ?? builder.config - - if (!normalizedDevToolsConfig?.enabled) { - return - } - - try { - const { start } = await import('@vitejs/devtools/cli-commands') - await start(normalizedDevToolsConfig.config) - } - catch (error: any) { - config.logger.error( - `Failed to run Vite DevTools: ${error?.message || error?.stack || error}`, - { error }, - ) + // Enable `rolldownOptions.devtools` if the environment is selected, or for all environments by default. + for (const environment of getDevToolsEnvironments(config)) { + environment.build.rolldownOptions.devtools ??= {} } }, }, diff --git a/test/exports/@vitejs/devtools.yaml b/test/exports/@vitejs/devtools.yaml index a377097e..97409b6a 100644 --- a/test/exports/@vitejs/devtools.yaml +++ b/test/exports/@vitejs/devtools.yaml @@ -10,5 +10,8 @@ ./dirs: dirClientStandalone: string dirDist: string +./integration: + DevToolsIntegration: function + runDevTools: function ./internal: getInternalContext: function From 589ba8e83c4d242b4fc9696ba0f1766f103eb4c3 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Thu, 30 Apr 2026 16:21:53 +0900 Subject: [PATCH 3/3] test: regenerate tsnapi snapshots for ./integration export and DevToolsConfig Co-Authored-By: Claude Opus 4.7 (1M context) --- .../tsnapi/@vitejs/devtools/config.snapshot.d.ts | 1 + .../@vitejs/devtools/integration.snapshot.d.ts | 13 +++++++++++++ .../tsnapi/@vitejs/devtools/integration.snapshot.js | 7 +++++++ 3 files changed, 21 insertions(+) create mode 100644 test/__snapshots__/tsnapi/@vitejs/devtools/integration.snapshot.d.ts create mode 100644 test/__snapshots__/tsnapi/@vitejs/devtools/integration.snapshot.js diff --git a/test/__snapshots__/tsnapi/@vitejs/devtools/config.snapshot.d.ts b/test/__snapshots__/tsnapi/@vitejs/devtools/config.snapshot.d.ts index c52bf04e..4d1c5392 100644 --- a/test/__snapshots__/tsnapi/@vitejs/devtools/config.snapshot.d.ts +++ b/test/__snapshots__/tsnapi/@vitejs/devtools/config.snapshot.d.ts @@ -4,6 +4,7 @@ // #region Interfaces export interface DevToolsConfig extends Partial { enabled: boolean; + environments?: string[]; clientAuth?: boolean; clientAuthTokens?: string[]; } diff --git a/test/__snapshots__/tsnapi/@vitejs/devtools/integration.snapshot.d.ts b/test/__snapshots__/tsnapi/@vitejs/devtools/integration.snapshot.d.ts new file mode 100644 index 00000000..66688c21 --- /dev/null +++ b/test/__snapshots__/tsnapi/@vitejs/devtools/integration.snapshot.d.ts @@ -0,0 +1,13 @@ +/** + * Generated by tsnapi — public API snapshot of `@vitejs/devtools/integration` + */ +// #region Interfaces +export interface DevToolsIntegrationOptions { + config: ResolvedConfig; +} +// #endregion + +// #region Functions +export declare function DevToolsIntegration(_: DevToolsIntegrationOptions): Plugin; +export declare function runDevTools(_: unknown): Promise; +// #endregion \ No newline at end of file diff --git a/test/__snapshots__/tsnapi/@vitejs/devtools/integration.snapshot.js b/test/__snapshots__/tsnapi/@vitejs/devtools/integration.snapshot.js new file mode 100644 index 00000000..2833d60d --- /dev/null +++ b/test/__snapshots__/tsnapi/@vitejs/devtools/integration.snapshot.js @@ -0,0 +1,7 @@ +/** + * Generated by tsnapi — public API snapshot of `@vitejs/devtools/integration` + */ +// #region Functions +export function DevToolsIntegration(_) {} +export async function runDevTools(_) {} +// #endregion \ No newline at end of file