diff --git a/packages/core/package.json b/packages/core/package.json index 23f9a730..c755840f 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..fe8832e6 --- /dev/null +++ b/packages/core/src/integration.ts @@ -0,0 +1,2 @@ +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 5febacff..7b0daa77 100644 --- a/packages/core/src/node/config.ts +++ b/packages/core/src/node/config.ts @@ -3,6 +3,10 @@ import { isObject } from 'devframe/node' export interface DevToolsConfig extends Partial { enabled: boolean + /** + * Vite environments to enable DevTools for. Defaults to all environments. + */ + environments?: string[] /** * Disable client authentication. * diff --git a/packages/core/src/node/plugins/integration.ts b/packages/core/src/node/plugins/integration.ts new file mode 100644 index 00000000..a578091d --- /dev/null +++ b/packages/core/src/node/plugins/integration.ts @@ -0,0 +1,55 @@ +import type { Plugin, ResolvedConfig, ViteBuilder } from 'vite' +import type { ResolvedDevToolsConfig } from '../config' + +type DevToolsEnvironment = ResolvedConfig['environments'][string] + +export interface DevToolsIntegrationOptions { + config: ResolvedConfig +} + +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) { + // 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/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', 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