@@ -12,24 +12,25 @@ const debug = require('debug')('webpack-dev-server');
12
12
const fs = require ( 'fs' ) ;
13
13
const net = require ( 'net' ) ;
14
14
15
- const portfinder = require ( 'portfinder' ) ;
16
15
const importLocal = require ( 'import-local' ) ;
17
16
18
17
const yargs = require ( 'yargs' ) ;
19
18
const webpack = require ( 'webpack' ) ;
20
19
21
20
const options = require ( './options' ) ;
22
-
23
21
const Server = require ( '../lib/Server' ) ;
24
22
25
23
const addEntries = require ( '../lib/utils/addEntries' ) ;
26
24
const colors = require ( '../lib/utils/colors' ) ;
27
25
const createConfig = require ( '../lib/utils/createConfig' ) ;
28
26
const createDomain = require ( '../lib/utils/createDomain' ) ;
29
27
const createLogger = require ( '../lib/utils/createLogger' ) ;
28
+ const defaultTo = require ( '../lib/utils/defaultTo' ) ;
29
+ const findPort = require ( '../lib/utils/findPort' ) ;
30
30
const getVersions = require ( '../lib/utils/getVersions' ) ;
31
31
const runBonjour = require ( '../lib/utils/runBonjour' ) ;
32
32
const status = require ( '../lib/utils/status' ) ;
33
+ const tryParseInt = require ( '../lib/utils/tryParseInt' ) ;
33
34
34
35
let server ;
35
36
@@ -93,6 +94,15 @@ const config = require('webpack-cli/bin/convert-argv')(yargs, argv, {
93
94
// we should use portfinder.
94
95
const DEFAULT_PORT = 8080 ;
95
96
97
+ // Try to find unused port and listen on it for 3 times,
98
+ // if port is not specified in options.
99
+ // Because NaN == null is false, defaultTo fails if parseInt returns NaN
100
+ // so the tryParseInt function is introduced to handle NaN
101
+ const defaultPortRetry = defaultTo (
102
+ tryParseInt ( process . env . DEFAULT_PORT_RETRY ) ,
103
+ 3
104
+ ) ;
105
+
96
106
function processOptions ( config ) {
97
107
// processOptions {Promise}
98
108
if ( typeof config . then === 'function' ) {
@@ -106,24 +116,7 @@ function processOptions(config) {
106
116
}
107
117
108
118
const options = createConfig ( config , argv , { port : DEFAULT_PORT } ) ;
109
-
110
- portfinder . basePort = DEFAULT_PORT ;
111
-
112
- if ( options . port != null ) {
113
- startDevServer ( config , options ) ;
114
-
115
- return ;
116
- }
117
-
118
- portfinder . getPort ( ( err , port ) => {
119
- if ( err ) {
120
- throw err ;
121
- }
122
-
123
- options . port = port ;
124
-
125
- startDevServer ( config , options ) ;
126
- } ) ;
119
+ startDevServer ( config , options ) ;
127
120
}
128
121
129
122
function startDevServer ( config , options ) {
@@ -209,21 +202,35 @@ function startDevServer(config, options) {
209
202
status ( uri , options , log , argv . color ) ;
210
203
} ) ;
211
204
} ) ;
212
- } else {
205
+ return ;
206
+ }
207
+
208
+ const startServer = ( ) => {
213
209
server . listen ( options . port , options . host , ( err ) => {
214
210
if ( err ) {
215
211
throw err ;
216
212
}
217
-
218
213
if ( options . bonjour ) {
219
214
runBonjour ( options ) ;
220
215
}
221
-
222
216
const uri = createDomain ( options , server . listeningApp ) + suffix ;
223
-
224
217
status ( uri , options , log , argv . color ) ;
225
218
} ) ;
219
+ } ;
220
+
221
+ if ( options . port ) {
222
+ startServer ( ) ;
223
+ return ;
226
224
}
225
+
226
+ // only run port finder if no port as been specified
227
+ findPort ( server , DEFAULT_PORT , defaultPortRetry , ( err , port ) => {
228
+ if ( err ) {
229
+ throw err ;
230
+ }
231
+ options . port = port ;
232
+ startServer ( ) ;
233
+ } ) ;
227
234
}
228
235
229
236
processOptions ( config ) ;
0 commit comments