diff --git a/bin/next-dev b/bin/next-dev index 0df5f875292c5..d5055a3cf2004 100755 --- a/bin/next-dev +++ b/bin/next-dev @@ -2,9 +2,10 @@ import 'source-map-support/register' import { resolve, join } from 'path' import parseArgs from 'minimist' -import { existsSync } from 'fs' +import { existsSync, readFileSync } from 'fs' import Server from '../server' import { printAndExit } from '../lib/utils' +import pkgUp from 'pkg-up' process.env.NODE_ENV = process.env.NODE_ENV || 'development' @@ -61,6 +62,15 @@ srv.start(argv.port) } }) .catch((err) => { - console.error(err) - process.exit(1) + if (err.code === 'EADDRINUSE') { + let errorMessage = `Port ${argv.port} is already in use.` + const pkgAppPath = pkgUp.sync('.') + const appPackage = JSON.parse(readFileSync(pkgAppPath, 'utf8')) + const nextScript = Object.entries(appPackage.scripts).find(scriptLine => scriptLine[1] === 'next') + if (nextScript) errorMessage += `\nUse \`npm run ${nextScript[0]} -- -p \`.` + console.error(errorMessage) + } else { + console.error(err) + } + process.nextTick(() => process.exit(1)) }) diff --git a/package.json b/package.json index 713580ca5af68..38dbe874634e7 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "mkdirp-then": "1.2.0", "mz": "2.6.0", "path-match": "1.2.4", + "pkg-up": "1.0.0", "react": "15.4.2", "react-dom": "15.4.2", "react-hot-loader": "3.0.0-beta.6", diff --git a/server/index.js b/server/index.js index 494e4422b2bd5..f08504ef6f883 100644 --- a/server/index.js +++ b/server/index.js @@ -119,10 +119,10 @@ export default class Server { await this.prepare() this.http = http.createServer(this.getRequestHandler()) await new Promise((resolve, reject) => { - this.http.listen(port, (err) => { - if (err) return reject(err) - resolve() - }) + // This code catches EADDRINUSE error if the port is already in use + this.http.on('error', reject) + this.http.on('listening', () => resolve()) + this.http.listen(port) }) }