diff --git a/packages/core/src/node/__tests__/config.test.ts b/packages/core/src/node/__tests__/config.test.ts index 2bceec77..7b8c0881 100644 --- a/packages/core/src/node/__tests__/config.test.ts +++ b/packages/core/src/node/__tests__/config.test.ts @@ -1,6 +1,9 @@ -import { describe, expect, it } from 'vitest' +import { ROLLDOWN_DEVTOOLS_ENV } from '@vitejs/devtools-kit/constants' +import { afterEach, describe, expect, it, vi } from 'vitest' import { isDevToolsEnabled, normalizeDevToolsConfig, resolveHost } from '../config' +afterEach(() => vi.unstubAllEnvs()) + describe('resolveHost', () => { it.each([ { host: undefined, expected: 'localhost' }, @@ -84,4 +87,11 @@ describe('normalizeDevToolsConfig', () => { expect(isDevToolsEnabled(config, 'serve')).toBe(false) expect(isDevToolsEnabled(config, 'build')).toBe(false) }) + + it('allows recording builds while preserving explicit disable and serve restrictions', () => { + vi.stubEnv(ROLLDOWN_DEVTOOLS_ENV, 'true') + expect(isDevToolsEnabled(normalizeDevToolsConfig({ apply: 'serve' }, undefined), 'build')).toBe(true) + expect(isDevToolsEnabled(normalizeDevToolsConfig({ apply: 'build' }, undefined), 'serve')).toBe(false) + expect(isDevToolsEnabled(normalizeDevToolsConfig({ enabled: false }, undefined), 'build')).toBe(false) + }) }) diff --git a/packages/core/src/node/__tests__/integration.test.ts b/packages/core/src/node/__tests__/integration.test.ts index cf6a79a0..ad6459fa 100644 --- a/packages/core/src/node/__tests__/integration.test.ts +++ b/packages/core/src/node/__tests__/integration.test.ts @@ -1,5 +1,6 @@ import type { Plugin, ResolvedConfig } from 'vite' -import { beforeEach, describe, expect, it, vi } from 'vitest' +import { ROLLDOWN_DEVTOOLS_ENV } from '@vitejs/devtools-kit/constants' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { normalizeDevToolsConfig } from '../config' import { DevToolsIntegration, runDevTools } from '../plugins/integration' import { startDevTools } from '../start' @@ -45,6 +46,8 @@ describe('devToolsIntegration', () => { vi.mocked(startDevTools).mockClear() }) + afterEach(() => vi.unstubAllEnvs()) + it('returns the existing DevTools plugins for serve', async () => { const plugins = await DevToolsIntegration({ ...createIntegrationOptions('serve'), @@ -109,6 +112,17 @@ describe('devToolsIntegration', () => { expect(plugins).toEqual([]) }) + it.each(['serve', 'all'] as const)('loads the build integration without starting standalone when apply is %s', async (apply) => { + vi.stubEnv(ROLLDOWN_DEVTOOLS_ENV, 'true') + const plugins = await DevToolsIntegration(createIntegrationOptions('build', createDevToolsConfig(apply))) + expect(plugins.map(plugin => plugin.name)).toContain('vite:devtools:integration') + const config = createResolvedConfig('build', { client: {} as never }) + Object.assign(config, { plugins, devtools: normalizeDevToolsConfig({ apply }, undefined) }) + + await runDevTools({ config }) + expect(startDevTools).not.toHaveBeenCalled() + }) + it('passes the resolved config to standalone DevTools', async () => { const config = createResolvedConfig('build', { client: {} as never }) const plugins = await DevToolsIntegration({ diff --git a/packages/core/src/node/config.ts b/packages/core/src/node/config.ts index 6fbe9328..49540fd5 100644 --- a/packages/core/src/node/config.ts +++ b/packages/core/src/node/config.ts @@ -2,6 +2,8 @@ import type { CreateInteractiveAuthOptions } from 'devframe/recipes/interactive- import type { McpSetting } from 'devframe/types' import type { StartOptions } from './cli-commands' import type { DevToolsUserOptions } from './plugin-options' +import process from 'node:process' +import { ROLLDOWN_DEVTOOLS_ENV } from '@vitejs/devtools-kit/constants' export type DevToolsApply = 'serve' | 'build' | 'all' @@ -111,5 +113,9 @@ export function isDevToolsEnabled( config: ResolvedDevToolsConfig, command: 'serve' | 'build', ): boolean { - return config.enabled && (config.apply === 'all' || config.apply === command) + return config.enabled && ( + config.apply === 'all' + || config.apply === command + || (command === 'build' && process.env[ROLLDOWN_DEVTOOLS_ENV] === 'true') + ) } diff --git a/packages/core/src/node/plugins/integration.ts b/packages/core/src/node/plugins/integration.ts index 34e56969..8ed2c68e 100644 --- a/packages/core/src/node/plugins/integration.ts +++ b/packages/core/src/node/plugins/integration.ts @@ -1,6 +1,7 @@ import type { Plugin, ResolvedConfig, ViteBuilder } from 'vite' import type { DevToolsConfig, ResolvedDevToolsConfig } from '../config' import process from 'node:process' +import { ROLLDOWN_DEVTOOLS_ENV } from '@vitejs/devtools-kit/constants' import { isDevToolsEnabled, normalizeDevToolsConfig } from '../config' import { DevToolsConfigPlugin } from './config' import { createDevToolsPlugins, resolveDevToolsPluginOptions } from './index' @@ -39,6 +40,10 @@ function getDevToolsEnvironments( export async function runDevTools( builder: unknown, ) { + // Skip the standalone server so the build process can exit. + if (process.env[ROLLDOWN_DEVTOOLS_ENV] === 'true') + return + const config = (builder as ViteBuilder).config if (!config.plugins.some(plugin => plugin.name === DEVTOOLS_BUILD_INTEGRATION_NAME)) return diff --git a/packages/kit/src/constants.ts b/packages/kit/src/constants.ts index 7a732b83..1aa84a0e 100644 --- a/packages/kit/src/constants.ts +++ b/packages/kit/src/constants.ts @@ -36,6 +36,9 @@ export const DEVTOOLS_WS_ROUTE = '__ws' export const DEVTOOLS_WS_PATH = `${DEVTOOLS_MOUNT_PATH}${DEVTOOLS_WS_ROUTE}` export const DEVTOOLS_DOCK_IMPORTS_VIRTUAL_ID = '/__devtools-client-imports.js' +/** Environment variable for recording Rolldown build sessions in an existing DevTools instance. */ +export const ROLLDOWN_DEVTOOLS_ENV = 'VITE_DEVTOOLS_ROLLDOWN' + /** * Dock id of the built-in Devframe Inspector (mounted from * `@devframes/plugin-inspect`). Shared between the node side (which pins the diff --git a/packages/rolldown/src/node/plugin.ts b/packages/rolldown/src/node/plugin.ts index ac7e08fc..776e482f 100644 --- a/packages/rolldown/src/node/plugin.ts +++ b/packages/rolldown/src/node/plugin.ts @@ -1,7 +1,7 @@ import type { PluginWithDevTools } from '@vitejs/devtools-kit' import process from 'node:process' +import { ROLLDOWN_DEVTOOLS_ENV } from '@vitejs/devtools-kit/constants' import { clientPublicDir } from '../dirs' -import { ROLLDOWN_DEVTOOLS_ENV } from './rolldown/build-runner' import { rpcFunctions } from './rpc/index' const ROLLDOWN_DEVTOOLS_BASE = '/__devtools-rolldown/' diff --git a/packages/rolldown/src/node/rolldown/__tests__/build-runner.test.ts b/packages/rolldown/src/node/rolldown/__tests__/build-runner.test.ts index 2ce52a01..740c9459 100644 --- a/packages/rolldown/src/node/rolldown/__tests__/build-runner.test.ts +++ b/packages/rolldown/src/node/rolldown/__tests__/build-runner.test.ts @@ -2,8 +2,9 @@ import type { ViteDevToolsNodeContext } from '@vitejs/devtools-kit' import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' +import { ROLLDOWN_DEVTOOLS_ENV } from '@vitejs/devtools-kit/constants' import { afterEach, describe, expect, it, vi } from 'vitest' -import { getBuildCommand, ROLLDOWN_DEVTOOLS_ENV, startBuild } from '../build-runner' +import { getBuildCommand, startBuild } from '../build-runner' const fixtures: string[] = [] diff --git a/packages/rolldown/src/node/rolldown/build-runner.ts b/packages/rolldown/src/node/rolldown/build-runner.ts index fb50f728..a5029e3c 100644 --- a/packages/rolldown/src/node/rolldown/build-runner.ts +++ b/packages/rolldown/src/node/rolldown/build-runner.ts @@ -1,5 +1,6 @@ import type { DevToolsChildProcessExecuteOptions, ViteDevToolsNodeContext } from '@vitejs/devtools-kit' import process from 'node:process' +import { ROLLDOWN_DEVTOOLS_ENV } from '@vitejs/devtools-kit/constants' import { isVitePlusInstalled } from '@vitejs/devtools-kit/node' import { diagnostics } from '../diagnostics' @@ -9,11 +10,6 @@ import { diagnostics } from '../diagnostics' * reusing a fixed id would throw "Terminal session ... already registered". */ const BUILD_SESSION_ID_BASE = 'vite:rolldown:build' -/** - * Env var the spawned build carries so the Rolldown DevTools plugin forces - * `rolldownOptions.devtools` on for that build (see `plugin.ts`). - */ -export const ROLLDOWN_DEVTOOLS_ENV = 'VITE_DEVTOOLS_ROLLDOWN' type BuildSession = Awaited> diff --git a/test/__snapshots__/tsnapi/@vitejs/devtools-kit/constants.snapshot.d.ts b/test/__snapshots__/tsnapi/@vitejs/devtools-kit/constants.snapshot.d.ts index 519f0500..8f364248 100644 --- a/test/__snapshots__/tsnapi/@vitejs/devtools-kit/constants.snapshot.d.ts +++ b/test/__snapshots__/tsnapi/@vitejs/devtools-kit/constants.snapshot.d.ts @@ -10,6 +10,7 @@ export declare const DEVTOOLS_MOUNT_PATH_NO_TRAILING_SLASH: string; export declare const DEVTOOLS_TERMINALS_DOCK_ID: string; export declare const DEVTOOLS_WS_PATH: string; export declare const DEVTOOLS_WS_ROUTE: string; +export declare const ROLLDOWN_DEVTOOLS_ENV: string; // #endregion // #region Other diff --git a/test/__snapshots__/tsnapi/@vitejs/devtools-kit/constants.snapshot.js b/test/__snapshots__/tsnapi/@vitejs/devtools-kit/constants.snapshot.js index 72f4ec27..c9338a67 100644 --- a/test/__snapshots__/tsnapi/@vitejs/devtools-kit/constants.snapshot.js +++ b/test/__snapshots__/tsnapi/@vitejs/devtools-kit/constants.snapshot.js @@ -10,6 +10,7 @@ export var DEVTOOLS_MOUNT_PATH_NO_TRAILING_SLASH /* const */ export var DEVTOOLS_TERMINALS_DOCK_ID /* const */ export var DEVTOOLS_WS_PATH /* const */ export var DEVTOOLS_WS_ROUTE /* const */ +export var ROLLDOWN_DEVTOOLS_ENV /* const */ // #endregion // #region Other