Skip to content

Commit

Permalink
Automatically use different port to start dev server for non-explicit…
Browse files Browse the repository at this point in the history
… port (#30736)

* Automatically using different port to start dev server for non-explicit port

* return correct port

* more reasonable changes

* fix isExplicitPort

* 1. rename isExplicitPort to allowRetry 2.restrict the number of retries

Co-authored-by: Steven <steven@ceriously.com>
  • Loading branch information
hyf0 and styfle committed Nov 11, 2021
1 parent 0c04f96 commit 4551571
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 4 deletions.
8 changes: 6 additions & 2 deletions packages/next/cli/next-dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const nextDev: cliCommand = (argv) => {
)
}
}

const allowRetry = !args['--port']
let port: number =
args['--port'] || (process.env.PORT && parseInt(process.env.PORT)) || 3000

Expand All @@ -88,7 +88,11 @@ const nextDev: cliCommand = (argv) => {
// some set-ups that rely on listening on other interfaces
const host = args['--hostname']

startServer({ dir, dev: true, isNextDevCommand: true }, port, host)
startServer(
{ dir, dev: true, isNextDevCommand: true, allowRetry },
port,
host
)
.then(async ({ app, actualPort }) => {
const appUrl = `http://${
!host || host === '0.0.0.0' ? 'localhost' : host
Expand Down
20 changes: 18 additions & 2 deletions packages/next/server/lib/start-server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import http from 'http'
import next from '../next'
import { warn } from '../../build/output/log'

export default async function start(
serverOptions: any,
Expand All @@ -18,8 +19,23 @@ export default async function start(
requestHandler = app.getRequestHandler()

await new Promise<void>((resolve, reject) => {
// This code catches EADDRINUSE error if the port is already in use
srv.on('error', reject)
let retryCount = 0
srv.on('error', (err: NodeJS.ErrnoException) => {
// This code catches EADDRINUSE error if the port is already in use
if (
err.code === 'EADDRINUSE' &&
serverOptions.allowRetry &&
port &&
retryCount < 10
) {
warn(`Port ${port} is in use, trying ${port + 1} instead.`)
port += 1
retryCount += 1
srv.listen(port, hostname)
} else {
reject(err)
}
})
srv.on('listening', () => resolve())
srv.listen(port, hostname)
})
Expand Down

0 comments on commit 4551571

Please sign in to comment.