From 431e1bb096083147a91712fb39acfce201716960 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Tue, 31 Jan 2023 14:39:03 +0100 Subject: [PATCH 1/7] feat(nuxi): cli-wrapper for self restart --- packages/nuxi/bin/nuxi.mjs | 34 ++++++++++++++++++++++++++++++++-- packages/nuxi/build.config.ts | 1 + packages/nuxi/src/cli-run.ts | 4 ++++ packages/nuxi/src/run.ts | 12 ++++++++++++ 4 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 packages/nuxi/src/cli-run.ts diff --git a/packages/nuxi/bin/nuxi.mjs b/packages/nuxi/bin/nuxi.mjs index b6bf5f6a686c..8f83783c2f55 100755 --- a/packages/nuxi/bin/nuxi.mjs +++ b/packages/nuxi/bin/nuxi.mjs @@ -1,3 +1,33 @@ #!/usr/bin/env node -process._startTime = Date.now() -import('../dist/cli.mjs').then(r => (r.default || r).main()) +import { fileURLToPath } from 'node:url' +import { execa } from 'execa' + +const EXIT_CODE_RESTART = 44 + +const ENTRY = new URL('../dist/cli-run.mjs', import.meta.url) + +async function start (preArgs, postArgs) { + const child = await execa( + 'node', + [ + ...preArgs, + fileURLToPath(ENTRY), + ...postArgs + ], + { + reject: false, + stdio: 'inherit', + env: { + ...process.env, + NUXI_CLI_WRAPPER: 'true' + } + } + ) + if (child.exitCode === EXIT_CODE_RESTART) { + await start(preArgs, postArgs) + } else { + process.exit(child.exitCode) + } +} + +start([], process.argv.slice(2)) diff --git a/packages/nuxi/build.config.ts b/packages/nuxi/build.config.ts index 294834abe472..2ab64b4f5a0a 100644 --- a/packages/nuxi/build.config.ts +++ b/packages/nuxi/build.config.ts @@ -10,6 +10,7 @@ export default defineBuildConfig({ }, entries: [ 'src/cli', + 'src/cli-run', 'src/index' ], externals: [ diff --git a/packages/nuxi/src/cli-run.ts b/packages/nuxi/src/cli-run.ts new file mode 100644 index 000000000000..56c55f22b4d7 --- /dev/null +++ b/packages/nuxi/src/cli-run.ts @@ -0,0 +1,4 @@ +// @ts-ignore +process._startTime = Date.now() +// @ts-ignore +import('./cli').then(r => (r.default || r).main()) diff --git a/packages/nuxi/src/run.ts b/packages/nuxi/src/run.ts index 4389c0f7f6f7..35b0ccb4932f 100644 --- a/packages/nuxi/src/run.ts +++ b/packages/nuxi/src/run.ts @@ -11,3 +11,15 @@ export async function runCommand (command: string, argv = process.argv.slice(2)) } await cmd.invoke(args) } + +/** + * Special exit code to restart the process + * + * Usage: + * ```ts + * if (process.env.NUXI_CLI_WRAPPER) { + * process.exit(EXIT_CODE_RESTART) + * } + * ``` + */ +export const EXIT_CODE_RESTART = 44 From a6a5d6fa319f7697645401699f87f30fc9f87021 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Tue, 31 Jan 2023 15:08:45 +0100 Subject: [PATCH 2/7] chore: properly bundle cli-warpper --- packages/nuxi/bin/nuxi.mjs | 33 +------------------------------ packages/nuxi/build.config.ts | 1 + packages/nuxi/src/cli-wrapper.ts | 34 ++++++++++++++++++++++++++++++++ packages/nuxi/src/constants.ts | 11 +++++++++++ packages/nuxi/src/index.ts | 1 + packages/nuxi/src/run.ts | 12 ----------- 6 files changed, 48 insertions(+), 44 deletions(-) create mode 100644 packages/nuxi/src/cli-wrapper.ts create mode 100644 packages/nuxi/src/constants.ts diff --git a/packages/nuxi/bin/nuxi.mjs b/packages/nuxi/bin/nuxi.mjs index 8f83783c2f55..f6b9116c9265 100755 --- a/packages/nuxi/bin/nuxi.mjs +++ b/packages/nuxi/bin/nuxi.mjs @@ -1,33 +1,2 @@ #!/usr/bin/env node -import { fileURLToPath } from 'node:url' -import { execa } from 'execa' - -const EXIT_CODE_RESTART = 44 - -const ENTRY = new URL('../dist/cli-run.mjs', import.meta.url) - -async function start (preArgs, postArgs) { - const child = await execa( - 'node', - [ - ...preArgs, - fileURLToPath(ENTRY), - ...postArgs - ], - { - reject: false, - stdio: 'inherit', - env: { - ...process.env, - NUXI_CLI_WRAPPER: 'true' - } - } - ) - if (child.exitCode === EXIT_CODE_RESTART) { - await start(preArgs, postArgs) - } else { - process.exit(child.exitCode) - } -} - -start([], process.argv.slice(2)) +import('./dist/cli-wrapper.mjs') diff --git a/packages/nuxi/build.config.ts b/packages/nuxi/build.config.ts index 2ab64b4f5a0a..522086d61af7 100644 --- a/packages/nuxi/build.config.ts +++ b/packages/nuxi/build.config.ts @@ -11,6 +11,7 @@ export default defineBuildConfig({ entries: [ 'src/cli', 'src/cli-run', + 'src/cli-wrapper', 'src/index' ], externals: [ diff --git a/packages/nuxi/src/cli-wrapper.ts b/packages/nuxi/src/cli-wrapper.ts new file mode 100644 index 000000000000..572e1e1c711b --- /dev/null +++ b/packages/nuxi/src/cli-wrapper.ts @@ -0,0 +1,34 @@ +/** + * This file is used to wrap the CLI entrypoint in a restartable process. + */ +import { fileURLToPath } from 'node:url' +import { execa } from 'execa' +import { EXIT_CODE_RESTART } from './constants' + +const ENTRY = new URL('./cli-run.mjs', import.meta.url) + +async function start (preArgs: string[], postArgs: string[]) { + const child = await execa( + 'node', + [ + ...preArgs, + fileURLToPath(ENTRY), + ...postArgs + ], + { + reject: false, + stdio: 'inherit', + env: { + ...process.env, + NUXI_CLI_WRAPPER: 'true' + } + } + ) + if (child.exitCode === EXIT_CODE_RESTART) { + await start(preArgs, postArgs) + } else { + process.exit(child.exitCode) + } +} + +start([], process.argv.slice(2)) diff --git a/packages/nuxi/src/constants.ts b/packages/nuxi/src/constants.ts new file mode 100644 index 000000000000..d717e7525f2c --- /dev/null +++ b/packages/nuxi/src/constants.ts @@ -0,0 +1,11 @@ +/** + * Special exit code to restart the process + * + * Usage: + * ```ts + * if (process.env.NUXI_CLI_WRAPPER) { + * process.exit(EXIT_CODE_RESTART) + * } + * ``` + */ +export const EXIT_CODE_RESTART = 44 diff --git a/packages/nuxi/src/index.ts b/packages/nuxi/src/index.ts index b8492c1b0168..119ab45c2acb 100755 --- a/packages/nuxi/src/index.ts +++ b/packages/nuxi/src/index.ts @@ -1 +1,2 @@ export * from './run' +export * from './constants' diff --git a/packages/nuxi/src/run.ts b/packages/nuxi/src/run.ts index 35b0ccb4932f..4389c0f7f6f7 100644 --- a/packages/nuxi/src/run.ts +++ b/packages/nuxi/src/run.ts @@ -11,15 +11,3 @@ export async function runCommand (command: string, argv = process.argv.slice(2)) } await cmd.invoke(args) } - -/** - * Special exit code to restart the process - * - * Usage: - * ```ts - * if (process.env.NUXI_CLI_WRAPPER) { - * process.exit(EXIT_CODE_RESTART) - * } - * ``` - */ -export const EXIT_CODE_RESTART = 44 From c0c4734a61dbc3574f41c3cf1d472cf720f5c092 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Tue, 31 Jan 2023 15:12:22 +0100 Subject: [PATCH 3/7] chore: fix path --- packages/nuxi/bin/nuxi.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nuxi/bin/nuxi.mjs b/packages/nuxi/bin/nuxi.mjs index f6b9116c9265..8dcfc256bd3f 100755 --- a/packages/nuxi/bin/nuxi.mjs +++ b/packages/nuxi/bin/nuxi.mjs @@ -1,2 +1,2 @@ #!/usr/bin/env node -import('./dist/cli-wrapper.mjs') +import('../dist/cli-wrapper.mjs') From 69fea57961f8bd2b6eab19bb605d3322d5963f85 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Tue, 31 Jan 2023 15:21:47 +0100 Subject: [PATCH 4/7] chore: compactiable with stub mode --- packages/nuxi/src/cli-wrapper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nuxi/src/cli-wrapper.ts b/packages/nuxi/src/cli-wrapper.ts index 572e1e1c711b..fad0956dce36 100644 --- a/packages/nuxi/src/cli-wrapper.ts +++ b/packages/nuxi/src/cli-wrapper.ts @@ -5,7 +5,7 @@ import { fileURLToPath } from 'node:url' import { execa } from 'execa' import { EXIT_CODE_RESTART } from './constants' -const ENTRY = new URL('./cli-run.mjs', import.meta.url) +const ENTRY = new URL('../dist/cli-run.mjs', import.meta.url) async function start (preArgs: string[], postArgs: string[]) { const child = await execa( From 06ed20997e356e86228d510d08600c7145a25f46 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Fri, 3 Feb 2023 12:11:15 +0100 Subject: [PATCH 5/7] perf: only enable subprocess in dev command --- packages/nuxi/src/cli-wrapper.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/nuxi/src/cli-wrapper.ts b/packages/nuxi/src/cli-wrapper.ts index fad0956dce36..8a20e6ffd5e7 100644 --- a/packages/nuxi/src/cli-wrapper.ts +++ b/packages/nuxi/src/cli-wrapper.ts @@ -5,14 +5,14 @@ import { fileURLToPath } from 'node:url' import { execa } from 'execa' import { EXIT_CODE_RESTART } from './constants' -const ENTRY = new URL('../dist/cli-run.mjs', import.meta.url) +const cliEntry = fileURLToPath(new URL('../dist/cli-run.mjs', import.meta.url)) -async function start (preArgs: string[], postArgs: string[]) { +async function startSubprocess (preArgs: string[], postArgs: string[]) { const child = await execa( 'node', [ ...preArgs, - fileURLToPath(ENTRY), + cliEntry, ...postArgs ], { @@ -25,10 +25,16 @@ async function start (preArgs: string[], postArgs: string[]) { } ) if (child.exitCode === EXIT_CODE_RESTART) { - await start(preArgs, postArgs) + await startSubprocess(preArgs, postArgs) } else { process.exit(child.exitCode) } } -start([], process.argv.slice(2)) +const args = process.argv.slice(2) +// only enable wrapper in dev command +if (args[0] === 'dev') { + startSubprocess([], args) +} else { + import(cliEntry) +} From 447f337b8439be7e94de70cab3268c93299d4d0b Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Wed, 1 Mar 2023 16:47:52 +0100 Subject: [PATCH 6/7] feat: add hook --- docs/3.api/4.advanced/1.hooks.md | 2 +- packages/nuxi/src/commands/dev.ts | 9 +++++++++ packages/schema/src/types/hooks.ts | 7 ++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/docs/3.api/4.advanced/1.hooks.md b/docs/3.api/4.advanced/1.hooks.md index af93555a065a..151446493d96 100644 --- a/docs/3.api/4.advanced/1.hooks.md +++ b/docs/3.api/4.advanced/1.hooks.md @@ -38,7 +38,7 @@ Hook | Arguments | Description `kit:compatibility` | `compatibility, issues` | Allows extending compatibility checks. `ready` | `nuxt` | Called after Nuxt initialization, when the Nuxt instance is ready to work. `close` | `nuxt` | Called when Nuxt instance is gracefully closing. -`restart` | - | Called to restart the current Nuxt instance. **This hook is currently only available on the [Edge Channel](/docs/guide/going-further/edge-channel/).** +`restart` | `{ hard?: boolean }` | To be called to restart the current Nuxt instance. **This hook is currently only available on the [Edge Channel](/docs/guide/going-further/edge-channel/).** `modules:before` | - | Called during Nuxt initialization, before installing user modules. `modules:done` | - | Called during Nuxt initialization, after installing user modules. `app:resolve` | `app` | Called after resolving the `app` instance. diff --git a/packages/nuxi/src/commands/dev.ts b/packages/nuxi/src/commands/dev.ts index 139d69e6299c..52cb53fa39e2 100644 --- a/packages/nuxi/src/commands/dev.ts +++ b/packages/nuxi/src/commands/dev.ts @@ -14,6 +14,7 @@ import { loadKit } from '../utils/kit' import { importModule } from '../utils/cjs' import { overrideEnv } from '../utils/env' import { writeNuxtManifest, loadNuxtManifest, cleanupNuxtDirs } from '../utils/nuxt' +import { EXIT_CODE_RESTART } from '../constants' import { defineNuxtCommand } from './index' export default defineNuxtCommand({ @@ -89,6 +90,14 @@ export default defineNuxtCommand({ } currentNuxt = await loadNuxt({ rootDir, dev: true, ready: false }) + // Hard restart + if (process.env.NUXI_CLI_WRAPPER) { + currentNuxt.hooks.hook('restart', (options) => { + if (options?.hard) { + process.exit(EXIT_CODE_RESTART) + } + }) + } currentNuxt.hooks.hookOnce('restart', () => load(true)) if (!isRestart) { diff --git a/packages/schema/src/types/hooks.ts b/packages/schema/src/types/hooks.ts index 566b89042b5a..ea19a809b7e7 100644 --- a/packages/schema/src/types/hooks.ts +++ b/packages/schema/src/types/hooks.ts @@ -77,7 +77,12 @@ export interface NuxtHooks { * Called to restart the current Nuxt instance. * @returns Promise */ - 'restart': () => HookResult + 'restart': (options?: { + /** + * Try to restart the whole process if supported + */ + hard?: boolean + }) => HookResult /** * Called during Nuxt initialization, before installing user modules. From 086e375565c85c69abf9b4b4e2f2544ffc8241c2 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Fri, 3 Mar 2023 00:41:51 +0100 Subject: [PATCH 7/7] chore: change code to 85 --- packages/nuxi/src/cli-wrapper.ts | 4 ++-- packages/nuxi/src/constants.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/nuxi/src/cli-wrapper.ts b/packages/nuxi/src/cli-wrapper.ts index 8a20e6ffd5e7..58a25250aba1 100644 --- a/packages/nuxi/src/cli-wrapper.ts +++ b/packages/nuxi/src/cli-wrapper.ts @@ -34,7 +34,7 @@ async function startSubprocess (preArgs: string[], postArgs: string[]) { const args = process.argv.slice(2) // only enable wrapper in dev command if (args[0] === 'dev') { - startSubprocess([], args) + await startSubprocess([], args) } else { - import(cliEntry) + await import(cliEntry) } diff --git a/packages/nuxi/src/constants.ts b/packages/nuxi/src/constants.ts index d717e7525f2c..36ebe5dfd8de 100644 --- a/packages/nuxi/src/constants.ts +++ b/packages/nuxi/src/constants.ts @@ -8,4 +8,4 @@ * } * ``` */ -export const EXIT_CODE_RESTART = 44 +export const EXIT_CODE_RESTART = 85