mirror of
https://github.com/nuxt/nuxt.git
synced 2025-02-12 03:38:07 +00:00
fix: dont force exit when it was explicitly disabled (#4973)
* fix: remove slash from warning text * fix: dont force-exit when explicitly disabled chore: add tests for force-exit behaviour * feat: default option value can be fn
This commit is contained in:
parent
3d2deacd3a
commit
4b82aa9d84
@ -13,9 +13,6 @@ export default class NuxtCommand {
|
|||||||
}
|
}
|
||||||
this.cmd = cmd
|
this.cmd = cmd
|
||||||
|
|
||||||
// If the cmd is a server then dont forcibly exit when the cmd has finished
|
|
||||||
this.isServer = cmd.isServer !== undefined ? cmd.isServer : Boolean(this.cmd.options.hostname)
|
|
||||||
|
|
||||||
this._argv = Array.from(argv)
|
this._argv = Array.from(argv)
|
||||||
this._parsedArgv = null // Lazy evaluate
|
this._parsedArgv = null // Lazy evaluate
|
||||||
}
|
}
|
||||||
@ -48,9 +45,9 @@ export default class NuxtCommand {
|
|||||||
|
|
||||||
const runResolve = Promise.resolve(this.cmd.run(this))
|
const runResolve = Promise.resolve(this.cmd.run(this))
|
||||||
|
|
||||||
// TODO: For v3 set timeout to 0 when force-exit === true
|
if (this.argv['force-exit']) {
|
||||||
if (!this.isServer || this.argv['force-exit']) {
|
const forceExitByUser = this.isUserSuppliedArg('force-exit')
|
||||||
runResolve.then(() => forceExit(this.cmd.name, forceExitTimeout))
|
runResolve.then(() => forceExit(this.cmd.name, forceExitByUser ? false : forceExitTimeout))
|
||||||
}
|
}
|
||||||
|
|
||||||
return runResolve
|
return runResolve
|
||||||
@ -102,6 +99,14 @@ export default class NuxtCommand {
|
|||||||
return new Generator(nuxt, builder)
|
return new Generator(nuxt, builder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isUserSuppliedArg(option) {
|
||||||
|
return this._argv.includes(`--${option}`) || this._argv.includes(`--no-${option}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
_getDefaultOptionValue(option) {
|
||||||
|
return typeof option.default === 'function' ? option.default(this.cmd) : option.default
|
||||||
|
}
|
||||||
|
|
||||||
_getMinimistOptions() {
|
_getMinimistOptions() {
|
||||||
const minimistOptions = {
|
const minimistOptions = {
|
||||||
alias: {},
|
alias: {},
|
||||||
@ -120,7 +125,7 @@ export default class NuxtCommand {
|
|||||||
minimistOptions[option.type].push(option.alias || name)
|
minimistOptions[option.type].push(option.alias || name)
|
||||||
}
|
}
|
||||||
if (option.default) {
|
if (option.default) {
|
||||||
minimistOptions.default[option.alias || name] = option.default
|
minimistOptions.default[option.alias || name] = this._getDefaultOptionValue(option)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,7 +140,7 @@ export default class NuxtCommand {
|
|||||||
const option = this.cmd.options[name]
|
const option = this.cmd.options[name]
|
||||||
|
|
||||||
let optionHelp = '--'
|
let optionHelp = '--'
|
||||||
optionHelp += option.type === 'boolean' && option.default ? 'no-' : ''
|
optionHelp += option.type === 'boolean' && this._getDefaultOptionValue(option) ? 'no-' : ''
|
||||||
optionHelp += name
|
optionHelp += name
|
||||||
if (option.alias) {
|
if (option.alias) {
|
||||||
optionHelp += `, -${option.alias}`
|
optionHelp += `, -${option.alias}`
|
||||||
|
@ -28,11 +28,12 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// TODO: Change this to default: false in Nuxt v3 (see related todo's)
|
|
||||||
'force-exit': {
|
'force-exit': {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
default: true,
|
default(cmd) {
|
||||||
description: 'Do not force Nuxt.js to exit after the command has finished (this option has no effect on commands which start a server)'
|
return ['build', 'generate'].includes(cmd.name)
|
||||||
|
},
|
||||||
|
description: 'Whether Nuxt.js should force exit after the command has finished'
|
||||||
},
|
},
|
||||||
version: {
|
version: {
|
||||||
alias: 'v',
|
alias: 'v',
|
||||||
|
@ -140,10 +140,10 @@ export function normalizeArg(arg, defaultValue) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function forceExit(cmdName, timeout) {
|
export function forceExit(cmdName, timeout) {
|
||||||
if (timeout) {
|
if (timeout !== false) {
|
||||||
const exitTimeout = setTimeout(() => {
|
const exitTimeout = setTimeout(() => {
|
||||||
const msg = `The command 'nuxt ${cmdName}' finished but did not exit after ${timeout}s
|
const msg = `The command 'nuxt ${cmdName}' finished but did not exit after ${timeout}s
|
||||||
This is most likely not caused by a bug in Nuxt.js\
|
This is most likely not caused by a bug in Nuxt.js
|
||||||
Make sure to cleanup all timers and listeners you or your plugins/modules start.
|
Make sure to cleanup all timers and listeners you or your plugins/modules start.
|
||||||
Nuxt.js will now force exit
|
Nuxt.js will now force exit
|
||||||
|
|
||||||
|
@ -18,10 +18,9 @@ exports[`cli/command builds help text 1`] = `
|
|||||||
--modern, -m Build/Start app for
|
--modern, -m Build/Start app for
|
||||||
modern browsers, e.g. server, client and
|
modern browsers, e.g. server, client and
|
||||||
false
|
false
|
||||||
--no-force-exit Do not force Nuxt.js
|
--force-exit Whether Nuxt.js
|
||||||
to exit after the command has finished
|
should force exit after the command has
|
||||||
(this option has no effect on commands
|
finished
|
||||||
which start a server)
|
|
||||||
--version, -v Display the Nuxt
|
--version, -v Display the Nuxt
|
||||||
version
|
version
|
||||||
--help, -h Display this message
|
--help, -h Display this message
|
||||||
|
@ -74,4 +74,36 @@ describe('build', () => {
|
|||||||
|
|
||||||
expect(options.modern).toBe(true)
|
expect(options.modern).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('build force-exits by default', async () => {
|
||||||
|
mockGetNuxt()
|
||||||
|
mockGetBuilder(Promise.resolve())
|
||||||
|
|
||||||
|
const cmd = NuxtCommand.from(build, ['build', '.'])
|
||||||
|
await cmd.run()
|
||||||
|
|
||||||
|
expect(utils.forceExit).toHaveBeenCalledTimes(1)
|
||||||
|
expect(utils.forceExit).toHaveBeenCalledWith('build', 5)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('build can set force exit explicitly', async () => {
|
||||||
|
mockGetNuxt()
|
||||||
|
mockGetBuilder(Promise.resolve())
|
||||||
|
|
||||||
|
const cmd = NuxtCommand.from(build, ['build', '.', '--force-exit'])
|
||||||
|
await cmd.run()
|
||||||
|
|
||||||
|
expect(utils.forceExit).toHaveBeenCalledTimes(1)
|
||||||
|
expect(utils.forceExit).toHaveBeenCalledWith('build', false)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('build can disable force exit explicitly', async () => {
|
||||||
|
mockGetNuxt()
|
||||||
|
mockGetBuilder(Promise.resolve())
|
||||||
|
|
||||||
|
const cmd = NuxtCommand.from(build, ['build', '.', '--no-force-exit'])
|
||||||
|
await cmd.run()
|
||||||
|
|
||||||
|
expect(utils.forceExit).not.toHaveBeenCalled()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -6,7 +6,6 @@ jest.mock('../../src/commands')
|
|||||||
|
|
||||||
describe('cli', () => {
|
describe('cli', () => {
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
// TODO: Below spyOn can be removed in v3 when force-exit is default false
|
|
||||||
jest.spyOn(utils, 'forceExit').mockImplementation(() => {})
|
jest.spyOn(utils, 'forceExit').mockImplementation(() => {})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -20,6 +19,7 @@ describe('cli', () => {
|
|||||||
|
|
||||||
await run()
|
await run()
|
||||||
expect(mockedCommand.run).toHaveBeenCalled()
|
expect(mockedCommand.run).toHaveBeenCalled()
|
||||||
|
expect(utils.forceExit).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('sets NODE_ENV=development for dev', async () => {
|
test('sets NODE_ENV=development for dev', async () => {
|
||||||
|
@ -6,7 +6,6 @@ describe('dev', () => {
|
|||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
dev = await import('../../src/commands/dev').then(m => m.default)
|
dev = await import('../../src/commands/dev').then(m => m.default)
|
||||||
// TODO: Below spyOn can be removed in v3 when force-exit is default false
|
|
||||||
jest.spyOn(utils, 'forceExit').mockImplementation(() => {})
|
jest.spyOn(utils, 'forceExit').mockImplementation(() => {})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -107,4 +106,35 @@ describe('dev', () => {
|
|||||||
|
|
||||||
expect(consola.error).toHaveBeenCalledWith(new Error('Listen Error'))
|
expect(consola.error).toHaveBeenCalledWith(new Error('Listen Error'))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('dev doesnt force-exit by default', async () => {
|
||||||
|
mockNuxt()
|
||||||
|
mockBuilder()
|
||||||
|
|
||||||
|
const cmd = NuxtCommand.from(dev, ['dev', '.'])
|
||||||
|
await cmd.run()
|
||||||
|
|
||||||
|
expect(utils.forceExit).not.toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('dev can set force exit explicitly', async () => {
|
||||||
|
mockNuxt()
|
||||||
|
mockBuilder()
|
||||||
|
|
||||||
|
const cmd = NuxtCommand.from(dev, ['dev', '.', '--force-exit'])
|
||||||
|
await cmd.run()
|
||||||
|
|
||||||
|
expect(utils.forceExit).toHaveBeenCalledTimes(1)
|
||||||
|
expect(utils.forceExit).toHaveBeenCalledWith('dev', false)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('dev can disable force exit explicitly', async () => {
|
||||||
|
mockNuxt()
|
||||||
|
mockBuilder()
|
||||||
|
|
||||||
|
const cmd = NuxtCommand.from(dev, ['dev', '.', '--no-force-exit'])
|
||||||
|
await cmd.run()
|
||||||
|
|
||||||
|
expect(utils.forceExit).not.toHaveBeenCalled()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -63,4 +63,49 @@ describe('generate', () => {
|
|||||||
|
|
||||||
expect(options.modern).toBe('client')
|
expect(options.modern).toBe('client')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('generate with modern mode', async () => {
|
||||||
|
mockGetNuxt()
|
||||||
|
mockGetGenerator(Promise.resolve())
|
||||||
|
|
||||||
|
const cmd = NuxtCommand.from(generate, ['generate', '.', '--m'])
|
||||||
|
|
||||||
|
const options = await cmd.getNuxtConfig()
|
||||||
|
|
||||||
|
await cmd.run()
|
||||||
|
|
||||||
|
expect(options.modern).toBe('client')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('generate force-exits by default', async () => {
|
||||||
|
mockGetNuxt()
|
||||||
|
mockGetGenerator(Promise.resolve())
|
||||||
|
|
||||||
|
const cmd = NuxtCommand.from(generate, ['generate', '.'])
|
||||||
|
await cmd.run()
|
||||||
|
|
||||||
|
expect(utils.forceExit).toHaveBeenCalledTimes(1)
|
||||||
|
expect(utils.forceExit).toHaveBeenCalledWith('generate', 5)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('generate can set force exit explicitly', async () => {
|
||||||
|
mockGetNuxt()
|
||||||
|
mockGetGenerator(Promise.resolve())
|
||||||
|
|
||||||
|
const cmd = NuxtCommand.from(generate, ['generate', '.', '--force-exit'])
|
||||||
|
await cmd.run()
|
||||||
|
|
||||||
|
expect(utils.forceExit).toHaveBeenCalledTimes(1)
|
||||||
|
expect(utils.forceExit).toHaveBeenCalledWith('generate', false)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('generate can disable force exit explicitly', async () => {
|
||||||
|
mockGetNuxt()
|
||||||
|
mockGetGenerator(Promise.resolve())
|
||||||
|
|
||||||
|
const cmd = NuxtCommand.from(generate, ['generate', '.', '--no-force-exit'])
|
||||||
|
await cmd.run()
|
||||||
|
|
||||||
|
expect(utils.forceExit).not.toHaveBeenCalled()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -7,7 +7,6 @@ describe('start', () => {
|
|||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
start = await import('../../src/commands/start').then(m => m.default)
|
start = await import('../../src/commands/start').then(m => m.default)
|
||||||
// TODO: Below spyOn can be removed in v3 when force-exit is default false
|
|
||||||
jest.spyOn(utils, 'forceExit').mockImplementation(() => {})
|
jest.spyOn(utils, 'forceExit').mockImplementation(() => {})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -35,4 +34,32 @@ describe('start', () => {
|
|||||||
await NuxtCommand.from(start).run()
|
await NuxtCommand.from(start).run()
|
||||||
expect(consola.fatal).not.toHaveBeenCalled()
|
expect(consola.fatal).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('start doesnt force-exit by default', async () => {
|
||||||
|
mockGetNuxtStart()
|
||||||
|
|
||||||
|
const cmd = NuxtCommand.from(start, ['start', '.'])
|
||||||
|
await cmd.run()
|
||||||
|
|
||||||
|
expect(utils.forceExit).not.toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('start can set force exit explicitly', async () => {
|
||||||
|
mockGetNuxtStart()
|
||||||
|
|
||||||
|
const cmd = NuxtCommand.from(start, ['start', '.', '--force-exit'])
|
||||||
|
await cmd.run()
|
||||||
|
|
||||||
|
expect(utils.forceExit).toHaveBeenCalledTimes(1)
|
||||||
|
expect(utils.forceExit).toHaveBeenCalledWith('start', false)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('start can disable force exit explicitly', async () => {
|
||||||
|
mockGetNuxtStart()
|
||||||
|
|
||||||
|
const cmd = NuxtCommand.from(start, ['start', '.', '--no-force-exit'])
|
||||||
|
await cmd.run()
|
||||||
|
|
||||||
|
expect(utils.forceExit).not.toHaveBeenCalled()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
@ -18,12 +18,12 @@ jest.mock('../../src/imports', () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
export const mockGetNuxt = (options, implementation) => {
|
export const mockGetNuxt = (options = {}, implementation) => {
|
||||||
Command.prototype.getNuxt = jest.fn().mockImplementationOnce(() => {
|
Command.prototype.getNuxt = jest.fn().mockImplementationOnce(() => {
|
||||||
return Object.assign({
|
return Object.assign({
|
||||||
hook: jest.fn(),
|
hook: jest.fn(),
|
||||||
options
|
options
|
||||||
}, implementation || {})
|
}, implementation)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user