mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-27 08:02:01 +00:00
fix(server): preserve random port when restarting (#5793)
This commit is contained in:
parent
0fc8ee41d1
commit
a0958f03f4
@ -5,6 +5,8 @@ import ip from 'ip'
|
|||||||
import consola from 'consola'
|
import consola from 'consola'
|
||||||
import pify from 'pify'
|
import pify from 'pify'
|
||||||
|
|
||||||
|
let RANDOM_PORT = '0'
|
||||||
|
|
||||||
export default class Listener {
|
export default class Listener {
|
||||||
constructor({ port, host, socket, https, app, dev, baseURL }) {
|
constructor({ port, host, socket, https, app, dev, baseURL }) {
|
||||||
// Options
|
// Options
|
||||||
@ -90,7 +92,7 @@ export default class Listener {
|
|||||||
this.listening = true
|
this.listening = true
|
||||||
}
|
}
|
||||||
|
|
||||||
serverErrorHandler(error) {
|
async serverErrorHandler(error) {
|
||||||
// Detect if port is not available
|
// Detect if port is not available
|
||||||
const addressInUse = error.code === 'EADDRINUSE'
|
const addressInUse = error.code === 'EADDRINUSE'
|
||||||
|
|
||||||
@ -100,11 +102,14 @@ export default class Listener {
|
|||||||
error.message = `Address \`${address}\` is already in use.`
|
error.message = `Address \`${address}\` is already in use.`
|
||||||
|
|
||||||
// Listen to a random port on dev as a fallback
|
// Listen to a random port on dev as a fallback
|
||||||
if (this.dev && !this.socket && this.port !== '0') {
|
if (this.dev && !this.socket && this.port !== RANDOM_PORT) {
|
||||||
consola.warn(error.message)
|
consola.warn(error.message)
|
||||||
consola.info('Trying a random port...')
|
consola.info('Trying a random port...')
|
||||||
this.port = '0'
|
this.port = RANDOM_PORT
|
||||||
return this.close().then(() => this.listen())
|
await this.close()
|
||||||
|
await this.listen()
|
||||||
|
RANDOM_PORT = this.port
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,7 +319,7 @@ describe('server: listener', () => {
|
|||||||
const listener = new Listener({})
|
const listener = new Listener({})
|
||||||
|
|
||||||
const error = new Error('server error')
|
const error = new Error('server error')
|
||||||
expect(() => listener.serverErrorHandler(error)).toThrow(error)
|
expect(listener.serverErrorHandler(error)).rejects.toThrow(error)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should throw address in use error', () => {
|
test('should throw address in use error', () => {
|
||||||
@ -329,7 +329,7 @@ describe('server: listener', () => {
|
|||||||
|
|
||||||
const addressInUse = new Error()
|
const addressInUse = new Error()
|
||||||
addressInUse.code = 'EADDRINUSE'
|
addressInUse.code = 'EADDRINUSE'
|
||||||
expect(() => listener.serverErrorHandler(addressInUse)).toThrow('Address `localhost:3000` is already in use.')
|
expect(listener.serverErrorHandler(addressInUse)).rejects.toThrow('Address `localhost:3000` is already in use.')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should throw address in use error for socket', () => {
|
test('should throw address in use error for socket', () => {
|
||||||
@ -338,7 +338,7 @@ describe('server: listener', () => {
|
|||||||
|
|
||||||
const addressInUse = new Error()
|
const addressInUse = new Error()
|
||||||
addressInUse.code = 'EADDRINUSE'
|
addressInUse.code = 'EADDRINUSE'
|
||||||
expect(() => listener.serverErrorHandler(addressInUse)).toThrow('Address `nuxt.socket` is already in use.')
|
expect(listener.serverErrorHandler(addressInUse)).rejects.toThrow('Address `nuxt.socket` is already in use.')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should fallback to a random port in address in use error', async () => {
|
test('should fallback to a random port in address in use error', async () => {
|
||||||
@ -362,6 +362,28 @@ describe('server: listener', () => {
|
|||||||
expect(listener.listen).toBeCalledTimes(1)
|
expect(listener.listen).toBeCalledTimes(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('should reuse last random port', async () => {
|
||||||
|
const listener = new Listener({ dev: true, host: 'localhost', port: 3000 })
|
||||||
|
listener.host = 'localhost'
|
||||||
|
listener.close = jest.fn()
|
||||||
|
listener.listen = function () {
|
||||||
|
if (this.port === '0') {
|
||||||
|
this.port = Math.random()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const addressInUse = new Error()
|
||||||
|
addressInUse.code = 'EADDRINUSE'
|
||||||
|
|
||||||
|
await listener.serverErrorHandler(addressInUse).catch(() => { })
|
||||||
|
const port1 = listener.port
|
||||||
|
await listener.serverErrorHandler(addressInUse).catch(() => { })
|
||||||
|
const port2 = listener.port
|
||||||
|
|
||||||
|
expect(port1).not.toBe(3000)
|
||||||
|
expect(port2).toBe(port1)
|
||||||
|
})
|
||||||
|
|
||||||
test('should close server', async () => {
|
test('should close server', async () => {
|
||||||
const listener = new Listener({})
|
const listener = new Listener({})
|
||||||
const server = mockServer()
|
const server = mockServer()
|
||||||
|
Loading…
Reference in New Issue
Block a user