mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-25 23:22:02 +00:00
refactor(nuxi): hard restart with communication channel (#19423)
This commit is contained in:
parent
3681bddfd5
commit
8fa3fba11f
@ -1,4 +1,5 @@
|
||||
// @ts-ignore
|
||||
process._startTime = Date.now()
|
||||
|
||||
// @ts-ignore
|
||||
import('./cli').then(r => (r.default || r).main())
|
||||
|
@ -2,39 +2,38 @@
|
||||
* 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'
|
||||
import { fork } from 'node:child_process'
|
||||
import type { ChildProcess } from 'node:child_process'
|
||||
|
||||
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') {
|
||||
startSubprocess([], args)
|
||||
// Only enable wrapper for nuxt dev command
|
||||
if (process.argv[2] === 'dev') {
|
||||
process.env.__CLI_ARGV__ = JSON.stringify(process.argv)
|
||||
startSubprocess()
|
||||
} else {
|
||||
import(cliEntry)
|
||||
}
|
||||
|
||||
function startSubprocess () {
|
||||
let childProc: ChildProcess
|
||||
|
||||
process.on('exit', () => {
|
||||
if (childProc) {
|
||||
childProc.kill()
|
||||
}
|
||||
})
|
||||
|
||||
start()
|
||||
|
||||
function start () {
|
||||
childProc = fork(cliEntry)
|
||||
childProc.on('close', (code) => { if (code) { process.exit(code) } })
|
||||
childProc.on('message', (message) => {
|
||||
if ((message as { type: string })?.type === 'nuxt:restart') {
|
||||
childProc.kill()
|
||||
startSubprocess()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import { showHelp } from './utils/help'
|
||||
import { showBanner } from './utils/banner'
|
||||
|
||||
async function _main () {
|
||||
const _argv = process.argv.slice(2)
|
||||
const _argv = (process.env.__CLI_ARGV__ ? JSON.parse(process.env.__CLI_ARGV__) : process.argv).slice(2)
|
||||
const args = mri(_argv, {
|
||||
boolean: [
|
||||
'no-clear'
|
||||
|
@ -14,7 +14,6 @@ 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({
|
||||
@ -90,15 +89,18 @@ 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))
|
||||
|
||||
currentNuxt.hooks.hookOnce('restart', async (options) => {
|
||||
if (options?.hard && process.send) {
|
||||
await listener.close().catch(() => {})
|
||||
await currentNuxt.close().catch(() => {})
|
||||
await watcher.close().catch(() => {})
|
||||
await distWatcher.close().catch(() => {})
|
||||
process.send({ type: 'nuxt:restart' })
|
||||
} else {
|
||||
await load(true)
|
||||
}
|
||||
})
|
||||
|
||||
if (!isRestart) {
|
||||
showURL()
|
||||
@ -121,7 +123,7 @@ export default defineNuxtCommand({
|
||||
await currentNuxt.ready()
|
||||
|
||||
await currentNuxt.hooks.callHook('listen', listener.server, listener)
|
||||
const address = listener.server.address() as AddressInfo
|
||||
const address = (listener.server.address() || {}) as AddressInfo
|
||||
currentNuxt.options.devServer.url = listener.url
|
||||
currentNuxt.options.devServer.port = address.port
|
||||
currentNuxt.options.devServer.host = address.address
|
||||
|
@ -1,11 +0,0 @@
|
||||
/**
|
||||
* 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
|
@ -1,2 +1 @@
|
||||
export * from './run'
|
||||
export * from './constants'
|
||||
|
Loading…
Reference in New Issue
Block a user