Skip to content

Commit c0a443e

Browse files
committed
Use detect-port to check if desired is already used.
Based on create-react-app and specifically facebook/create-react-app#101 In production, will exit(1) if the port is in use.
1 parent 3d44b58 commit c0a443e

File tree

6 files changed

+55
-7
lines changed

6 files changed

+55
-7
lines changed

bin/next-dev

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import parseArgs from 'minimist'
44
import { exists } from 'mz/fs'
55
import Server from '../server'
66
import clean from '../server/build/clean'
7+
import run from './util/run';
78

89
const argv = parseArgs(process.argv.slice(2), {
910
alias: {
@@ -21,8 +22,7 @@ const dir = resolve(argv._[0] || '.')
2122
clean(dir)
2223
.then(async () => {
2324
const srv = new Server({ dir, dev: true, hotReload: true })
24-
await srv.start(argv.port)
25-
console.log('> Ready on http://localhost:%d', argv.port)
25+
await run({ srv, port: argv.port })
2626

2727
// Check if pages dir exists and warn if not
2828
if (!(await exists(join(dir, 'pages')))) {

bin/next-start

+3-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import { resolve } from 'path'
44
import parseArgs from 'minimist'
55
import Server from '../server'
6+
import run from './util/run';
67

78
const argv = parseArgs(process.argv.slice(2), {
89
alias: {
@@ -18,10 +19,8 @@ const argv = parseArgs(process.argv.slice(2), {
1819
const dir = resolve(argv._[0] || '.')
1920

2021
const srv = new Server({ dir })
21-
srv.start(argv.port)
22-
.then(() => {
23-
console.log('> Ready on http://localhost:%d', argv.port)
24-
})
22+
23+
run({ srv, port: argv.port, shouldPrompt: false })
2524
.catch((err) => {
2625
console.error(err)
2726
process.exit(1)

bin/util/prompt.js

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import rl from 'readline';
2+
3+
export default function (question) {
4+
const rlInterface = rl.createInterface({
5+
input: process.stdin,
6+
output: process.stdout,
7+
});
8+
9+
return new Promise((resolve) => {
10+
rlInterface.question(question + '\n', function(answer) {
11+
rlInterface.close();
12+
resolve(answer);
13+
});
14+
});
15+
};

bin/util/run.js

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import prompt from './prompt';
2+
import detect from 'detect-port';
3+
import chalk from 'chalk';
4+
5+
const defaults = { shouldPrompt: true };
6+
export default async function run(opts) {
7+
const { srv, port: desiredPort, shouldPrompt } = { ...defaults, ...opts };
8+
const port = await detect(desiredPort);
9+
if (port !== desiredPort) {
10+
if (!shouldPrompt) {
11+
// Fail early if no prompt
12+
console.error(`Error: Something is already running at port ${desiredPort}. Exiting.`);
13+
process.exit(1);
14+
}
15+
16+
// Prompt the user to change the port.
17+
let shouldChangePort = false;
18+
if (shouldPrompt) {
19+
const question = chalk.red(`Something is already running at port ${desiredPort}.\n` +
20+
`Would you like to run the app on port ${port} instead? [Y/n]`);
21+
const answer = await prompt(question);
22+
shouldChangePort = !answer.length || answer.match(/^yes|y$/i);
23+
}
24+
if (!shouldChangePort) {
25+
console.log(chalk.red('Exiting.'));
26+
process.exit(0);
27+
}
28+
}
29+
await srv.start(port);
30+
console.log(`Ready on ${chalk.cyan(`http://localhost:${port}`)}`);
31+
}

gulpfile.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ gulp.task('compile', [
2626
])
2727

2828
gulp.task('compile-bin', () => {
29-
return gulp.src('bin/*')
29+
return gulp.src(['bin/*', 'bin/**/*.js'])
3030
.pipe(cache('bin'))
3131
.pipe(babel(babelOptions))
3232
.pipe(gulp.dest('dist/bin'))

package.json

+3
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@
4747
"babel-preset-es2015": "6.16.0",
4848
"babel-preset-react": "6.16.0",
4949
"babel-runtime": "6.11.6",
50+
"chalk": "^1.1.3",
5051
"cross-spawn": "4.0.2",
5152
"del": "2.2.2",
53+
"detect-port": "^1.0.1",
5254
"glamor": "2.17.10",
5355
"glob-promise": "1.0.6",
5456
"htmlescape": "1.1.1",
@@ -59,6 +61,7 @@
5961
"react": "15.3.2",
6062
"react-dom": "15.3.2",
6163
"react-hot-loader": "3.0.0-beta.6",
64+
"readline": "^1.3.0",
6265
"send": "0.14.1",
6366
"strip-ansi": "3.0.1",
6467
"url": "0.11.0",

0 commit comments

Comments
 (0)