feat(nuxi): cli wrapper for self restart (#18641)

This commit is contained in:
Anthony Fu 2023-03-03 14:45:38 +01:00 committed by GitHub
parent 78f1c330c1
commit db5ea91916
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 75 additions and 4 deletions

View File

@ -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/).** <!-- stabilityedge -->
`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/).** <!-- stabilityedge -->
`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.

View File

@ -1,3 +1,2 @@
#!/usr/bin/env node
process._startTime = Date.now()
import('../dist/cli.mjs').then(r => (r.default || r).main())
import('../dist/cli-wrapper.mjs')

View File

@ -10,6 +10,8 @@ export default defineBuildConfig({
},
entries: [
'src/cli',
'src/cli-run',
'src/cli-wrapper',
'src/index'
],
externals: [

View File

@ -0,0 +1,4 @@
// @ts-ignore
process._startTime = Date.now()
// @ts-ignore
import('./cli').then(r => (r.default || r).main())

View File

@ -0,0 +1,40 @@
/**
* 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 cliEntry = fileURLToPath(new URL('../dist/cli-run.mjs', import.meta.url))
async function startSubprocess (preArgs: string[], postArgs: string[]) {
const child = await execa(
'node',
[
...preArgs,
cliEntry,
...postArgs
],
{
reject: false,
stdio: 'inherit',
env: {
...process.env,
NUXI_CLI_WRAPPER: 'true'
}
}
)
if (child.exitCode === EXIT_CODE_RESTART) {
await startSubprocess(preArgs, postArgs)
} else {
process.exit(child.exitCode)
}
}
const args = process.argv.slice(2)
// only enable wrapper in dev command
if (args[0] === 'dev') {
await startSubprocess([], args)
} else {
await import(cliEntry)
}

View File

@ -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) {

View File

@ -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 = 85

View File

@ -1 +1,2 @@
export * from './run'
export * from './constants'

View File

@ -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.