Skip to content

Commit

Permalink
feat(cli): add watchStdin option to exit when stdin ends
Browse files Browse the repository at this point in the history
  • Loading branch information
stevehodgkiss committed Jan 15, 2025
1 parent 0802662 commit 5b4f2d6
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 7 deletions.
4 changes: 4 additions & 0 deletions packages/vite/src/node/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ cli
'--force',
`[boolean] force the optimizer to ignore the cache and re-bundle`,
)
.option('--watchStdin', `[boolean] watch stdin and exit on EOF`)
.action(async (root: string, options: ServerOptions & GlobalCLIOptions) => {
filterDuplicateOptions(options)
// output structure is preserved even after bundling so require()
Expand Down Expand Up @@ -364,6 +365,7 @@ cli
.option('--strictPort', `[boolean] exit if specified port is already in use`)
.option('--open [path]', `[boolean | string] open browser on startup`)
.option('--outDir <dir>', `[string] output directory (default: dist)`)
.option('--watchStdin', `[boolean] watch stdin and exit on EOF`)
.action(
async (
root: string,
Expand All @@ -373,6 +375,7 @@ cli
open?: boolean | string
strictPort?: boolean
outDir?: string
watchStdin?: boolean
} & GlobalCLIOptions,
) => {
filterDuplicateOptions(options)
Expand All @@ -392,6 +395,7 @@ cli
strictPort: options.strictPort,
host: options.host,
open: options.open,
watchStdin: options.watchStdin,
},
})
server.printUrls()
Expand Down
4 changes: 4 additions & 0 deletions packages/vite/src/node/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ export interface CommonServerOptions {
* Specify server response headers.
*/
headers?: HttpServerHeaders
/**
* Watch stdin and exit on EOF
*/
watchStdin?: boolean
}

/**
Expand Down
5 changes: 3 additions & 2 deletions packages/vite/src/node/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export function resolvePreviewOptions(
proxy: preview?.proxy ?? server.proxy,
cors: preview?.cors ?? server.cors,
headers: preview?.headers ?? server.headers,
watchStdin: preview?.watchStdin ?? server.watchStdin,
}
}

Expand Down Expand Up @@ -151,7 +152,7 @@ export async function preview(
// Promise used by `server.close()` to ensure `closeServer()` is only called once
let closeServerPromise: Promise<void> | undefined
const closeServer = async () => {
teardownSIGTERMListener(closeServerAndExit)
teardownSIGTERMListener(config.preview.watchStdin, closeServerAndExit)
await closeHttpServer()
server.resolvedUrls = null
}
Expand Down Expand Up @@ -188,7 +189,7 @@ export async function preview(
}
}

setupSIGTERMListener(closeServerAndExit)
setupSIGTERMListener(config.preview.watchStdin, closeServerAndExit)

// apply server hooks from plugins
const postHooks: ((() => void) | void)[] = []
Expand Down
5 changes: 3 additions & 2 deletions packages/vite/src/node/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ export async function _createServer(
let closeServerPromise: Promise<void> | undefined
const closeServer = async () => {
if (!middlewareMode) {
teardownSIGTERMListener(closeServerAndExit)
teardownSIGTERMListener(config.server.watchStdin, closeServerAndExit)
}

await Promise.allSettled([
Expand Down Expand Up @@ -766,7 +766,7 @@ export async function _createServer(
}

if (!middlewareMode) {
setupSIGTERMListener(closeServerAndExit)
setupSIGTERMListener(config.server.watchStdin, closeServerAndExit)
}

const onHMRUpdate = async (
Expand Down Expand Up @@ -1045,6 +1045,7 @@ export const serverConfigDefaults = Object.freeze({
host: 'localhost',
https: undefined,
open: false,
watchStdin: false,
proxy: undefined,
cors: true,
headers: {},
Expand Down
10 changes: 7 additions & 3 deletions packages/vite/src/node/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1544,24 +1544,28 @@ const parentSigtermCallback: SigtermCallback = async (signal, exitCode) => {
}

export const setupSIGTERMListener = (
watchStdin: boolean,
callback: (signal?: 'SIGTERM', exitCode?: number) => Promise<void>,
): void => {
if (sigtermCallbacks.size === 0) {
process.once('SIGTERM', parentSigtermCallback)
if (process.env.CI !== 'true') {
if (watchStdin) {
process.stdin.on('end', parentSigtermCallback)
// resume stdin to allow the server to exit on EOF
process.stdin.resume()
}
}
sigtermCallbacks.add(callback)
}

export const teardownSIGTERMListener = (
callback: Parameters<typeof setupSIGTERMListener>[0],
watchStdin: boolean,
callback: Parameters<typeof setupSIGTERMListener>[1],
): void => {
sigtermCallbacks.delete(callback)
if (sigtermCallbacks.size === 0) {
process.off('SIGTERM', parentSigtermCallback)
if (process.env.CI !== 'true') {
if (watchStdin) {
process.stdin.off('end', parentSigtermCallback)
}
}
Expand Down

0 comments on commit 5b4f2d6

Please sign in to comment.