diff --git a/packages/vite/src/node/cli.ts b/packages/vite/src/node/cli.ts index afd69e769e8467..9abe80a8d4ceef 100644 --- a/packages/vite/src/node/cli.ts +++ b/packages/vite/src/node/cli.ts @@ -1,4 +1,3 @@ -import { performance } from 'node:perf_hooks' import { cac } from 'cac' import colors from 'picocolors' import type { BuildOptions } from './build' @@ -105,25 +104,7 @@ cli await server.listen() - const info = server.config.logger.info - - // @ts-ignore - const viteStartTime = global.__vite_start_time ?? false - const startupDurationString = viteStartTime - ? colors.dim( - `ready in ${colors.reset( - colors.bold(Math.ceil(performance.now() - viteStartTime)) - )} ms` - ) - : '' - - info( - `\n ${colors.green( - `${colors.bold('VITE')} v${VERSION}` - )} ${startupDurationString}\n`, - { clear: !server.config.logger.hasWarned } - ) - + server.printReadyInfo() server.printUrls() } catch (e) { createLogger(options.logLevel).error( diff --git a/packages/vite/src/node/server/hmr.ts b/packages/vite/src/node/server/hmr.ts index e5d93fad8629de..6355d965c1a849 100644 --- a/packages/vite/src/node/server/hmr.ts +++ b/packages/vite/src/node/server/hmr.ts @@ -54,6 +54,8 @@ export async function handleHMRUpdate( const isEnv = config.inlineConfig.envFile !== false && (fileName === '.env' || fileName.startsWith('.env.')) + + const keepAddress = config.server.keepAddress if (isConfig || isConfigDependency || isEnv) { // auto restart server debugHmr(`[config change] ${colors.dim(shortFile)}`) @@ -108,6 +110,11 @@ export async function handleHMRUpdate( clear: true, timestamp: true }) + if (keepAddress) { + server.printReadyInfo() + server.printUrls() + } + ws.send({ type: 'full-reload', path: config.server.middlewareMode @@ -128,12 +135,14 @@ export function updateModules( file: string, modules: ModuleNode[], timestamp: number, - { config, ws }: ViteDevServer + { config, ws, printReadyInfo, printUrls }: ViteDevServer ): void { const updates: Update[] = [] const invalidatedModules = new Set() let needFullReload = false + const keepAddress = config.server.keepAddress + for (const mod of modules) { invalidate(mod, timestamp, invalidatedModules) if (needFullReload) { @@ -169,6 +178,10 @@ export function updateModules( clear: true, timestamp: true }) + if (keepAddress) { + printReadyInfo() + printUrls() + } ws.send({ type: 'full-reload' }) @@ -186,6 +199,10 @@ export function updateModules( .join('\n'), { clear: true, timestamp: true } ) + if (keepAddress) { + printReadyInfo() + printUrls() + } ws.send({ type: 'update', updates diff --git a/packages/vite/src/node/server/index.ts b/packages/vite/src/node/server/index.ts index 5e8296e5ad3aad..b1cd87677b247a 100644 --- a/packages/vite/src/node/server/index.ts +++ b/packages/vite/src/node/server/index.ts @@ -42,7 +42,7 @@ import { initDepsOptimizer, initDevSsrDepsOptimizer } from '../optimizer' -import { CLIENT_DIR } from '../constants' +import { CLIENT_DIR, VERSION } from '../constants' import type { Logger } from '../logger' import { printServerUrls } from '../logger' import { invalidatePackageData } from '../packages' @@ -123,6 +123,12 @@ export interface ServerOptions extends CommonServerOptions { * in a future minor version without following semver */ force?: boolean + + /** + * Always keep address + * @default false + */ + keepAddress?: boolean } export interface ResolvedServerOptions extends ServerOptions { @@ -263,6 +269,11 @@ export interface ViteDevServer { * Print server urls */ printUrls(): void + + /** + * Print server start ready info + */ + printReadyInfo(): void /** * Restart the server. * @@ -436,6 +447,24 @@ export async function createServer( ) } }, + printReadyInfo() { + const info = server.config.logger.info + // @ts-ignore + const viteStartTime = global.__vite_start_time ?? false + const startupDurationString = viteStartTime + ? colors.dim( + `ready in ${colors.reset( + colors.bold(Math.ceil(performance.now() - viteStartTime)) + )} ms` + ) + : '' + info( + `\n ${colors.green( + `${colors.bold('VITE')} v${VERSION}` + )} ${startupDurationString}\n`, + { clear: !server.config.logger.hasWarned } + ) + }, async restart(forceOptimize?: boolean) { if (!server._restartPromise) { server._forceOptimizeOnRestart = !!forceOptimize