From a24a4893f4f41c43d6a421b874ce09f30687646a Mon Sep 17 00:00:00 2001 From: btea <2356281422@qq.com> Date: Mon, 24 Apr 2023 11:46:35 +0800 Subject: [PATCH 1/2] feat: preview mode add keyboard shortcuts --- packages/vite/src/node/cli.ts | 4 +- packages/vite/src/node/shortcuts.ts | 82 +++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 1 deletion(-) diff --git a/packages/vite/src/node/cli.ts b/packages/vite/src/node/cli.ts index d18ab93fd0213f..27bd5642596781 100644 --- a/packages/vite/src/node/cli.ts +++ b/packages/vite/src/node/cli.ts @@ -8,7 +8,7 @@ import type { ServerOptions } from './server' import type { LogLevel } from './logger' import { createLogger } from './logger' import { VERSION } from './constants' -import { bindShortcuts } from './shortcuts' +import { bindPreviewShortcuts, bindShortcuts } from './shortcuts' import { resolveConfig } from '.' const cli = cac('vite') @@ -291,6 +291,7 @@ cli }, ) +// preview cli .command('preview [root]', 'locally preview production build') .option('--host [host]', `[string] specify hostname`) @@ -332,6 +333,7 @@ cli }, }) server.printUrls() + bindPreviewShortcuts(server) } catch (e) { createLogger(options.logLevel).error( colors.red(`error when starting preview server:\n${e.stack}`), diff --git a/packages/vite/src/node/shortcuts.ts b/packages/vite/src/node/shortcuts.ts index 651e1e0f773176..1361172782e209 100644 --- a/packages/vite/src/node/shortcuts.ts +++ b/packages/vite/src/node/shortcuts.ts @@ -1,6 +1,8 @@ import colors from 'picocolors' import type { ViteDevServer } from './server' import { isDefined } from './utils' +import type { PreviewServer } from './preview' +import { openBrowser } from './server/openBrowser' export type BindShortcutsOptions = { /** @@ -119,3 +121,83 @@ const BASE_SHORTCUTS: CLIShortcut[] = [ }, }, ] + +type PreviewShortcuts = { + key: string + description: string + action: (server: PreviewServer) => void +} + +export function bindPreviewShortcuts(server: PreviewServer): void { + if (!server.httpServer || !process.stdin.isTTY || process.env.CI) { + return + } + server.config.logger.info( + colors.dim(colors.green(' ➜')) + + colors.dim(' press ') + + colors.bold('h') + + colors.dim(' to show help'), + ) + let actionRunning = false + const onInput = async (input: string) => { + // ctrl+c or ctrl+d + if (input === '\x03' || input === '\x04') { + try { + server.httpServer.close() + } finally { + process.exit(1) + } + } + if (actionRunning) return + if (input === 'h') { + server.config.logger.info( + [ + '', + colors.bold(' Shortcuts'), + ...previewShortcuts.map( + (shortcut) => + colors.dim(' press ') + + colors.bold(shortcut.key) + + colors.dim(` to ${shortcut.description}`), + ), + ].join('\n'), + ) + } + + const shortcut = previewShortcuts.find((shortcut) => shortcut.key === input) + if (!shortcut) return + actionRunning = true + shortcut.action(server) + actionRunning = false + } + + process.stdin.setRawMode(true) + + process.stdin.on('data', onInput).setEncoding('utf8').resume() + + server.httpServer.on('close', () => { + process.stdin.off('data', onInput).pause() + }) +} + +const previewShortcuts: PreviewShortcuts[] = [ + { + key: 'o', + description: 'open in browser', + action(server) { + const url = server.resolvedUrls.local[0] + openBrowser(url, true, server.config.logger) + }, + }, + { + key: 'q', + description: 'quit', + action(server) { + try { + server.httpServer.close() + } finally { + process.exit() + } + }, + }, +] From 906fade654b98e5c19fde6a905e878b0aabfcdbe Mon Sep 17 00:00:00 2001 From: bluwy Date: Thu, 29 Jun 2023 14:46:03 +0800 Subject: [PATCH 2/2] refactor: deduplicate code --- packages/vite/src/node/cli.ts | 4 +- packages/vite/src/node/shortcuts.ts | 106 +++++++++------------------- 2 files changed, 36 insertions(+), 74 deletions(-) diff --git a/packages/vite/src/node/cli.ts b/packages/vite/src/node/cli.ts index 33e2d7333a034b..df858f403f80c5 100644 --- a/packages/vite/src/node/cli.ts +++ b/packages/vite/src/node/cli.ts @@ -8,7 +8,7 @@ import type { ServerOptions } from './server' import type { LogLevel } from './logger' import { createLogger } from './logger' import { VERSION } from './constants' -import { bindPreviewShortcuts, bindShortcuts } from './shortcuts' +import { bindShortcuts } from './shortcuts' import { resolveConfig } from '.' const cli = cac('vite') @@ -345,7 +345,7 @@ cli }, }) server.printUrls() - bindPreviewShortcuts(server) + bindShortcuts(server, { print: true }) } catch (e) { createLogger(options.logLevel).error( colors.red(`error when starting preview server:\n${e.stack}`), diff --git a/packages/vite/src/node/shortcuts.ts b/packages/vite/src/node/shortcuts.ts index 1361172782e209..fad8c1e19689fc 100644 --- a/packages/vite/src/node/shortcuts.ts +++ b/packages/vite/src/node/shortcuts.ts @@ -4,30 +4,35 @@ import { isDefined } from './utils' import type { PreviewServer } from './preview' import { openBrowser } from './server/openBrowser' -export type BindShortcutsOptions = { +export type BindShortcutsOptions = { /** * Print a one line hint to the terminal. */ print?: boolean - customShortcuts?: (CLIShortcut | undefined | null)[] + customShortcuts?: (CLIShortcut | undefined | null)[] } -export type CLIShortcut = { +export type CLIShortcut = { key: string description: string - action(server: ViteDevServer): void | Promise + action(server: Server): void | Promise } -export function bindShortcuts( - server: ViteDevServer, - opts: BindShortcutsOptions, +export function bindShortcuts( + server: Server, + opts?: BindShortcutsOptions, ): void { if (!server.httpServer || !process.stdin.isTTY || process.env.CI) { return } - server._shortcutsOptions = opts - if (opts.print) { + const isDev = isDevServer(server) + + if (isDev) { + server._shortcutsOptions = opts + } + + if (opts?.print) { server.config.logger.info( colors.dim(colors.green(' ➜')) + colors.dim(' press ') + @@ -36,16 +41,25 @@ export function bindShortcuts( ) } - const shortcuts = (opts.customShortcuts ?? []) + const shortcuts = (opts?.customShortcuts ?? []) .filter(isDefined) - .concat(BASE_SHORTCUTS) + // @ts-expect-error passing the right types, but typescript can't detect it + .concat(isDev ? BASE_DEV_SHORTCUTS : BASE_PREVIEW_SHORTCUTS) let actionRunning = false const onInput = async (input: string) => { // ctrl+c or ctrl+d if (input === '\x03' || input === '\x04') { - await server.close().finally(() => process.exit(1)) + try { + if (isDev) { + await server.close() + } else { + server.httpServer.close() + } + } finally { + process.exit(1) + } return } @@ -83,7 +97,13 @@ export function bindShortcuts( }) } -const BASE_SHORTCUTS: CLIShortcut[] = [ +function isDevServer( + server: ViteDevServer | PreviewServer, +): server is ViteDevServer { + return 'pluginContainer' in server +} + +const BASE_DEV_SHORTCUTS: CLIShortcut[] = [ { key: 'r', description: 'restart the server', @@ -122,65 +142,7 @@ const BASE_SHORTCUTS: CLIShortcut[] = [ }, ] -type PreviewShortcuts = { - key: string - description: string - action: (server: PreviewServer) => void -} - -export function bindPreviewShortcuts(server: PreviewServer): void { - if (!server.httpServer || !process.stdin.isTTY || process.env.CI) { - return - } - server.config.logger.info( - colors.dim(colors.green(' ➜')) + - colors.dim(' press ') + - colors.bold('h') + - colors.dim(' to show help'), - ) - let actionRunning = false - const onInput = async (input: string) => { - // ctrl+c or ctrl+d - if (input === '\x03' || input === '\x04') { - try { - server.httpServer.close() - } finally { - process.exit(1) - } - } - if (actionRunning) return - if (input === 'h') { - server.config.logger.info( - [ - '', - colors.bold(' Shortcuts'), - ...previewShortcuts.map( - (shortcut) => - colors.dim(' press ') + - colors.bold(shortcut.key) + - colors.dim(` to ${shortcut.description}`), - ), - ].join('\n'), - ) - } - - const shortcut = previewShortcuts.find((shortcut) => shortcut.key === input) - if (!shortcut) return - actionRunning = true - shortcut.action(server) - actionRunning = false - } - - process.stdin.setRawMode(true) - - process.stdin.on('data', onInput).setEncoding('utf8').resume() - - server.httpServer.on('close', () => { - process.stdin.off('data', onInput).pause() - }) -} - -const previewShortcuts: PreviewShortcuts[] = [ +const BASE_PREVIEW_SHORTCUTS: CLIShortcut[] = [ { key: 'o', description: 'open in browser',