webpack-dev-server 3.1.3 → 3.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,304 +2,206 @@
2
2
 
3
3
  'use strict';
4
4
 
5
- /* eslint global-require: off, import/order: off, no-console: off, import/no-extraneous-dependencies: off */
6
- require('../lib/polyfills');
7
-
5
+ /* eslint-disable
6
+ import/order,
7
+ import/no-extraneous-dependencies,
8
+ global-require,
9
+ no-shadow,
10
+ no-console,
11
+ multiline-ternary,
12
+ arrow-parens,
13
+ array-bracket-spacing,
14
+ space-before-function-paren
15
+ */
8
16
  const debug = require('debug')('webpack-dev-server');
17
+
9
18
  const fs = require('fs');
10
19
  const net = require('net');
11
20
  const path = require('path');
12
- const importLocal = require('import-local');
13
- const open = require('opn');
21
+
14
22
  const portfinder = require('portfinder');
15
- const addDevServerEntrypoints = require('../lib/util/addDevServerEntrypoints');
16
- const createDomain = require('../lib/util/createDomain'); // eslint-disable-line
17
- const createLog = require('../lib/createLog');
23
+ const importLocal = require('import-local');
24
+
25
+ const yargs = require('yargs');
26
+ const webpack = require('webpack');
27
+
28
+ const options = require('./options');
29
+
30
+ const {
31
+ colors,
32
+ status,
33
+ version,
34
+ bonjour,
35
+ defaultTo
36
+ } = require('./utils');
37
+
38
+ const Server = require('../lib/Server');
39
+
40
+ const addEntries = require('../lib/utils/addEntries');
41
+ const createDomain = require('../lib/utils/createDomain');
42
+ const createLogger = require('../lib/utils/createLogger');
43
+
44
+ let server;
45
+
46
+ const signals = [ 'SIGINT', 'SIGTERM' ];
47
+
48
+ signals.forEach((signal) => {
49
+ process.on(signal, () => {
50
+ if (server) {
51
+ server.close(() => {
52
+ // eslint-disable-next-line no-process-exit
53
+ process.exit();
54
+ });
55
+ } else {
56
+ // eslint-disable-next-line no-process-exit
57
+ process.exit();
58
+ }
59
+ });
60
+ });
18
61
 
19
62
  // Prefer the local installation of webpack-dev-server
20
63
  if (importLocal(__filename)) {
21
64
  debug('Using local install of webpack-dev-server');
65
+
22
66
  return;
23
67
  }
24
68
 
25
- const Server = require('../lib/Server');
26
- const webpack = require('webpack'); // eslint-disable-line
27
-
28
69
  try {
29
70
  require.resolve('webpack-cli');
30
- } catch (e) {
31
- console.error('The CLI moved into a separate package: webpack-cli.');
32
- console.error("Please install 'webpack-cli' in addition to webpack itself to use the CLI.");
33
- console.error('-> When using npm: npm install webpack-cli -D');
34
- console.error('-> When using yarn: yarn add webpack-cli -D');
35
- process.exitCode = 1;
36
- }
37
-
38
- function versionInfo() {
39
- return `webpack-dev-server ${require('../package.json').version}\n` +
40
- `webpack ${require('webpack/package.json').version}`;
41
- }
71
+ } catch (err) {
72
+ console.error('The CLI moved into a separate package: webpack-cli');
73
+ console.error('Please install \'webpack-cli\' in addition to webpack itself to use the CLI');
74
+ console.error('-> When using npm: npm i -D webpack-cli');
75
+ console.error('-> When using yarn: yarn add -D webpack-cli');
42
76
 
43
- function colorInfo(useColor, msg) {
44
- if (useColor) {
45
- // Make text blue and bold, so it *pops*
46
- return `\u001b[1m\u001b[34m${msg}\u001b[39m\u001b[22m`;
47
- }
48
- return msg;
49
- }
50
-
51
- function colorError(useColor, msg) {
52
- if (useColor) {
53
- // Make text red and bold, so it *pops*
54
- return `\u001b[1m\u001b[31m${msg}\u001b[39m\u001b[22m`;
55
- }
56
- return msg;
77
+ process.exitCode = 1;
57
78
  }
58
79
 
59
- // eslint-disable-next-line
60
- const defaultTo = (value, def) => value == null ? def : value;
61
-
62
- const yargs = require('yargs')
63
- .usage(`${versionInfo()}\nUsage: https://webpack.js.org/configuration/dev-server/`);
80
+ yargs.usage(
81
+ `${version()}\nUsage: https://webpack.js.org/configuration/dev-server/`
82
+ );
64
83
 
65
84
  require('webpack-cli/bin/config-yargs')(yargs);
66
-
67
85
  // It is important that this is done after the webpack yargs config,
68
86
  // so it overrides webpack's version info.
69
- yargs
70
- .version(versionInfo());
87
+ yargs.version(version());
88
+ yargs.options(options);
71
89
 
72
- const ADVANCED_GROUP = 'Advanced options:';
73
- const DISPLAY_GROUP = 'Stats options:';
74
- const SSL_GROUP = 'SSL options:';
75
- const CONNECTION_GROUP = 'Connection options:';
76
- const RESPONSE_GROUP = 'Response options:';
77
- const BASIC_GROUP = 'Basic options:';
90
+ const argv = yargs.argv;
78
91
 
92
+ const config = require('webpack-cli/bin/convert-argv')(yargs, argv, {
93
+ outputFilename: '/bundle.js'
94
+ });
79
95
  // Taken out of yargs because we must know if
80
96
  // it wasn't given by the user, in which case
81
97
  // we should use portfinder.
82
98
  const DEFAULT_PORT = 8080;
83
99
 
84
- yargs.options({
85
- bonjour: {
86
- type: 'boolean',
87
- describe: 'Broadcasts the server via ZeroConf networking on start'
88
- },
89
- lazy: {
90
- type: 'boolean',
91
- describe: 'Lazy'
92
- },
93
- inline: {
94
- type: 'boolean',
95
- default: true,
96
- describe: 'Inline mode (set to false to disable including client scripts like livereload)'
97
- },
98
- progress: {
99
- type: 'boolean',
100
- describe: 'Print compilation progress in percentage',
101
- group: BASIC_GROUP
102
- },
103
- 'hot-only': {
104
- type: 'boolean',
105
- describe: 'Do not refresh page if HMR fails',
106
- group: ADVANCED_GROUP
107
- },
108
- stdin: {
109
- type: 'boolean',
110
- describe: 'close when stdin ends'
111
- },
112
- open: {
113
- type: 'string',
114
- describe: 'Open the default browser, or optionally specify a browser name'
115
- },
116
- useLocalIp: {
117
- type: 'boolean',
118
- describe: 'Open default browser with local IP'
119
- },
120
- 'open-page': {
121
- type: 'string',
122
- describe: 'Open default browser with the specified page',
123
- requiresArg: true
124
- },
125
- color: {
126
- type: 'boolean',
127
- alias: 'colors',
128
- default: function supportsColor() {
129
- return require('supports-color');
130
- },
131
- group: DISPLAY_GROUP,
132
- describe: 'Enables/Disables colors on the console'
133
- },
134
- info: {
135
- type: 'boolean',
136
- group: DISPLAY_GROUP,
137
- default: true,
138
- describe: 'Info'
139
- },
140
- quiet: {
141
- type: 'boolean',
142
- group: DISPLAY_GROUP,
143
- describe: 'Quiet'
144
- },
145
- 'client-log-level': {
146
- type: 'string',
147
- group: DISPLAY_GROUP,
148
- default: 'info',
149
- describe: 'Log level in the browser (info, warning, error or none)'
150
- },
151
- https: {
152
- type: 'boolean',
153
- group: SSL_GROUP,
154
- describe: 'HTTPS'
155
- },
156
- key: {
157
- type: 'string',
158
- describe: 'Path to a SSL key.',
159
- group: SSL_GROUP
160
- },
161
- cert: {
162
- type: 'string',
163
- describe: 'Path to a SSL certificate.',
164
- group: SSL_GROUP
165
- },
166
- cacert: {
167
- type: 'string',
168
- describe: 'Path to a SSL CA certificate.',
169
- group: SSL_GROUP
170
- },
171
- pfx: {
172
- type: 'string',
173
- describe: 'Path to a SSL pfx file.',
174
- group: SSL_GROUP
175
- },
176
- 'pfx-passphrase': {
177
- type: 'string',
178
- describe: 'Passphrase for pfx file.',
179
- group: SSL_GROUP
180
- },
181
- 'content-base': {
182
- type: 'string',
183
- describe: 'A directory or URL to serve HTML content from.',
184
- group: RESPONSE_GROUP
185
- },
186
- 'watch-content-base': {
187
- type: 'boolean',
188
- describe: 'Enable live-reloading of the content-base.',
189
- group: RESPONSE_GROUP
190
- },
191
- 'history-api-fallback': {
192
- type: 'boolean',
193
- describe: 'Fallback to /index.html for Single Page Applications.',
194
- group: RESPONSE_GROUP
195
- },
196
- compress: {
197
- type: 'boolean',
198
- describe: 'Enable gzip compression',
199
- group: RESPONSE_GROUP
200
- },
201
- port: {
202
- describe: 'The port',
203
- group: CONNECTION_GROUP
204
- },
205
- 'disable-host-check': {
206
- type: 'boolean',
207
- describe: 'Will not check the host',
208
- group: CONNECTION_GROUP
209
- },
210
- socket: {
211
- type: 'String',
212
- describe: 'Socket to listen',
213
- group: CONNECTION_GROUP
214
- },
215
- public: {
216
- type: 'string',
217
- describe: 'The public hostname/ip address of the server',
218
- group: CONNECTION_GROUP
219
- },
220
- host: {
221
- type: 'string',
222
- default: 'localhost',
223
- describe: 'The hostname/ip address the server will bind to',
224
- group: CONNECTION_GROUP
225
- },
226
- 'allowed-hosts': {
227
- type: 'string',
228
- describe: 'A comma-delimited string of hosts that are allowed to access the dev server',
229
- group: CONNECTION_GROUP
230
- }
231
- });
232
-
233
- const argv = yargs.argv;
234
- const wpOpt = require('webpack-cli/bin/convert-argv')(yargs, argv, {
235
- outputFilename: '/bundle.js'
236
- });
237
-
238
- function processOptions(webpackOptions) {
239
- // process Promise
240
- if (typeof webpackOptions.then === 'function') {
241
- webpackOptions.then(processOptions).catch((err) => {
100
+ function processOptions (config) {
101
+ // processOptions {Promise}
102
+ if (typeof config.then === 'function') {
103
+ config.then(processOptions).catch((err) => {
242
104
  console.error(err.stack || err);
243
- process.exit(); // eslint-disable-line
105
+ // eslint-disable-next-line no-process-exit
106
+ process.exit();
244
107
  });
108
+
245
109
  return;
246
110
  }
247
111
 
248
- const firstWpOpt = Array.isArray(webpackOptions) ? webpackOptions[0] : webpackOptions;
112
+ const firstWpOpt = Array.isArray(config)
113
+ ? config[0]
114
+ : config;
249
115
 
250
- const options = webpackOptions.devServer || firstWpOpt.devServer || {};
116
+ const options = config.devServer || firstWpOpt.devServer || {};
251
117
 
252
- if (argv.bonjour) { options.bonjour = true; }
118
+ if (argv.bonjour) {
119
+ options.bonjour = true;
120
+ }
253
121
 
254
- if (argv.host !== 'localhost' || !options.host) { options.host = argv.host; }
122
+ if (argv.host !== 'localhost' || !options.host) {
123
+ options.host = argv.host;
124
+ }
255
125
 
256
- if (argv['allowed-hosts']) { options.allowedHosts = argv['allowed-hosts'].split(','); }
126
+ if (argv['allowed-hosts']) {
127
+ options.allowedHosts = argv['allowed-hosts'].split(',');
128
+ }
257
129
 
258
- if (argv.public) { options.public = argv.public; }
130
+ if (argv.public) {
131
+ options.public = argv.public;
132
+ }
259
133
 
260
- if (argv.socket) { options.socket = argv.socket; }
134
+ if (argv.socket) {
135
+ options.socket = argv.socket;
136
+ }
261
137
 
262
- if (argv.progress) { options.progress = argv.progress; }
138
+ if (argv.progress) {
139
+ options.progress = argv.progress;
140
+ }
263
141
 
264
142
  if (!options.publicPath) {
265
143
  // eslint-disable-next-line
266
144
  options.publicPath = firstWpOpt.output && firstWpOpt.output.publicPath || '';
267
- if (!/^(https?:)?\/\//.test(options.publicPath) && options.publicPath[0] !== '/') {
145
+
146
+ if (
147
+ !/^(https?:)?\/\//.test(options.publicPath) &&
148
+ options.publicPath[0] !== '/'
149
+ ) {
268
150
  options.publicPath = `/${options.publicPath}`;
269
151
  }
270
152
  }
271
153
 
272
- if (!options.filename) { options.filename = firstWpOpt.output && firstWpOpt.output.filename; }
154
+ if (!options.filename) {
155
+ options.filename = firstWpOpt.output && firstWpOpt.output.filename;
156
+ }
273
157
 
274
- if (!options.watchOptions) { options.watchOptions = firstWpOpt.watchOptions; }
158
+ if (!options.watchOptions) {
159
+ options.watchOptions = firstWpOpt.watchOptions;
160
+ }
275
161
 
276
162
  if (argv.stdin) {
277
163
  process.stdin.on('end', () => {
278
- process.exit(0); // eslint-disable-line no-process-exit
164
+ // eslint-disable-next-line no-process-exit
165
+ process.exit(0);
279
166
  });
167
+
280
168
  process.stdin.resume();
281
169
  }
282
170
 
283
- if (!options.hot) { options.hot = argv.hot; }
171
+ if (!options.hot) {
172
+ options.hot = argv.hot;
173
+ }
284
174
 
285
- if (!options.hotOnly) { options.hotOnly = argv['hot-only']; }
175
+ if (!options.hotOnly) {
176
+ options.hotOnly = argv['hot-only'];
177
+ }
286
178
 
287
- if (!options.clientLogLevel) { options.clientLogLevel = argv['client-log-level']; }
179
+ if (!options.clientLogLevel) {
180
+ options.clientLogLevel = argv['client-log-level'];
181
+ }
288
182
 
289
183
  // eslint-disable-next-line
290
184
  if (options.contentBase === undefined) {
291
185
  if (argv['content-base']) {
292
186
  options.contentBase = argv['content-base'];
187
+
293
188
  if (Array.isArray(options.contentBase)) {
294
- options.contentBase = options.contentBase.map(val => path.resolve(val));
295
- } else if (/^[0-9]$/.test(options.contentBase)) { options.contentBase = +options.contentBase; } else if (!/^(https?:)?\/\//.test(options.contentBase)) { options.contentBase = path.resolve(options.contentBase); }
296
- // It is possible to disable the contentBase by using `--no-content-base`, which results in arg["content-base"] = false
189
+ options.contentBase = options.contentBase.map((p) => path.resolve(p));
190
+ } else if (/^[0-9]$/.test(options.contentBase)) {
191
+ options.contentBase = +options.contentBase;
192
+ } else if (!/^(https?:)?\/\//.test(options.contentBase)) {
193
+ options.contentBase = path.resolve(options.contentBase);
194
+ }
195
+ // It is possible to disable the contentBase by using
196
+ // `--no-content-base`, which results in arg["content-base"] = false
297
197
  } else if (argv['content-base'] === false) {
298
198
  options.contentBase = false;
299
199
  }
300
200
  }
301
201
 
302
- if (argv['watch-content-base']) { options.watchContentBase = true; }
202
+ if (argv['watch-content-base']) {
203
+ options.watchContentBase = true;
204
+ }
303
205
 
304
206
  if (!options.stats) {
305
207
  options.stats = {
@@ -308,35 +210,76 @@ function processOptions(webpackOptions) {
308
210
  };
309
211
  }
310
212
 
311
- if (typeof options.stats === 'object' && typeof options.stats.colors === 'undefined') {
312
- options.stats = Object.assign({}, options.stats, { colors: argv.color });
213
+ if (
214
+ typeof options.stats === 'object' &&
215
+ typeof options.stats.colors === 'undefined'
216
+ ) {
217
+ options.stats = Object.assign(
218
+ {},
219
+ options.stats,
220
+ { colors: argv.color }
221
+ );
313
222
  }
314
223
 
315
- if (argv.lazy) { options.lazy = true; }
224
+ if (argv.lazy) {
225
+ options.lazy = true;
226
+ }
316
227
 
317
- if (!argv.info) { options.noInfo = true; }
228
+ if (!argv.info) {
229
+ options.noInfo = true;
230
+ }
318
231
 
319
- if (argv.quiet) { options.quiet = true; }
232
+ if (argv.quiet) {
233
+ options.quiet = true;
234
+ }
320
235
 
321
- if (argv.https) { options.https = true; }
236
+ if (argv.https) {
237
+ options.https = true;
238
+ }
322
239
 
323
- if (argv.cert) { options.cert = fs.readFileSync(path.resolve(argv.cert)); }
240
+ if (argv.cert) {
241
+ options.cert = fs.readFileSync(
242
+ path.resolve(argv.cert)
243
+ );
244
+ }
324
245
 
325
- if (argv.key) { options.key = fs.readFileSync(path.resolve(argv.key)); }
246
+ if (argv.key) {
247
+ options.key = fs.readFileSync(
248
+ path.resolve(argv.key)
249
+ );
250
+ }
326
251
 
327
- if (argv.cacert) { options.ca = fs.readFileSync(path.resolve(argv.cacert)); }
252
+ if (argv.cacert) {
253
+ options.ca = fs.readFileSync(
254
+ path.resolve(argv.cacert)
255
+ );
256
+ }
328
257
 
329
- if (argv.pfx) { options.pfx = fs.readFileSync(path.resolve(argv.pfx)); }
258
+ if (argv.pfx) {
259
+ options.pfx = fs.readFileSync(
260
+ path.resolve(argv.pfx)
261
+ );
262
+ }
330
263
 
331
- if (argv['pfx-passphrase']) { options.pfxPassphrase = argv['pfx-passphrase']; }
264
+ if (argv['pfx-passphrase']) {
265
+ options.pfxPassphrase = argv['pfx-passphrase'];
266
+ }
332
267
 
333
- if (argv.inline === false) { options.inline = false; }
268
+ if (argv.inline === false) {
269
+ options.inline = false;
270
+ }
334
271
 
335
- if (argv['history-api-fallback']) { options.historyApiFallback = true; }
272
+ if (argv['history-api-fallback']) {
273
+ options.historyApiFallback = true;
274
+ }
336
275
 
337
- if (argv.compress) { options.compress = true; }
276
+ if (argv.compress) {
277
+ options.compress = true;
278
+ }
338
279
 
339
- if (argv['disable-host-check']) { options.disableHostCheck = true; }
280
+ if (argv['disable-host-check']) {
281
+ options.disableHostCheck = true;
282
+ }
340
283
 
341
284
  if (argv['open-page']) {
342
285
  options.open = true;
@@ -347,42 +290,57 @@ function processOptions(webpackOptions) {
347
290
  options.open = argv.open !== '' ? argv.open : true;
348
291
  }
349
292
 
350
- if (options.open && !options.openPage) { options.openPage = ''; }
351
-
352
- if (argv.useLocalIp) { options.useLocalIp = true; }
293
+ if (options.open && !options.openPage) {
294
+ options.openPage = '';
295
+ }
353
296
 
297
+ if (argv.useLocalIp) {
298
+ options.useLocalIp = true;
299
+ }
354
300
  // Kind of weird, but ensures prior behavior isn't broken in cases
355
301
  // that wouldn't throw errors. E.g. both argv.port and options.port
356
302
  // were specified, but since argv.port is 8080, options.port will be
357
303
  // tried first instead.
358
- options.port = argv.port === DEFAULT_PORT ? defaultTo(options.port, argv.port) : defaultTo(argv.port, options.port);
304
+ options.port = argv.port === DEFAULT_PORT
305
+ ? defaultTo(options.port, argv.port)
306
+ : defaultTo(argv.port, options.port);
359
307
 
360
308
  if (options.port != null) {
361
- startDevServer(webpackOptions, options);
309
+ startDevServer(config, options);
310
+
362
311
  return;
363
312
  }
364
313
 
365
314
  portfinder.basePort = DEFAULT_PORT;
315
+
366
316
  portfinder.getPort((err, port) => {
367
- if (err) throw err;
317
+ if (err) {
318
+ throw err;
319
+ }
320
+
368
321
  options.port = port;
369
- startDevServer(webpackOptions, options);
322
+
323
+ startDevServer(config, options);
370
324
  });
371
325
  }
372
326
 
373
- function startDevServer(webpackOptions, options) {
374
- const log = createLog(options);
375
- addDevServerEntrypoints(webpackOptions, options);
327
+ function startDevServer(config, options) {
328
+ const log = createLogger(options);
329
+
330
+ addEntries(config, options);
376
331
 
377
332
  let compiler;
333
+
378
334
  try {
379
- compiler = webpack(webpackOptions);
380
- } catch (e) {
381
- if (e instanceof webpack.WebpackOptionsValidationError) {
382
- log.error(colorError(options.stats.colors, e.message));
383
- process.exit(1); // eslint-disable-line
335
+ compiler = webpack(config);
336
+ } catch (err) {
337
+ if (err instanceof webpack.WebpackOptionsValidationError) {
338
+ log.error(colors.error(options.stats.colors, err.message));
339
+ // eslint-disable-next-line no-process-exit
340
+ process.exit(1);
384
341
  }
385
- throw e;
342
+
343
+ throw err;
386
344
  }
387
345
 
388
346
  if (options.progress) {
@@ -393,112 +351,74 @@ function startDevServer(webpackOptions, options) {
393
351
 
394
352
  const suffix = (options.inline !== false || options.lazy === true ? '/' : '/webpack-dev-server/');
395
353
 
396
- let server;
397
354
  try {
398
355
  server = new Server(compiler, options, log);
399
- } catch (e) {
400
- const OptionsValidationError = require('../lib/OptionsValidationError');
401
- if (e instanceof OptionsValidationError) {
402
- log.error(colorError(options.stats.colors, e.message));
403
- process.exit(1); // eslint-disable-line
356
+ } catch (err) {
357
+ if (err.name === 'ValidationError') {
358
+ log.error(colors.error(options.stats.colors, err.message));
359
+ // eslint-disable-next-line no-process-exit
360
+ process.exit(1);
404
361
  }
405
- throw e;
406
- }
407
362
 
408
- ['SIGINT', 'SIGTERM'].forEach((sig) => {
409
- process.on(sig, () => {
410
- server.close(() => {
411
- process.exit(); // eslint-disable-line no-process-exit
412
- });
413
- });
414
- });
363
+ throw err;
364
+ }
415
365
 
416
366
  if (options.socket) {
417
367
  server.listeningApp.on('error', (e) => {
418
368
  if (e.code === 'EADDRINUSE') {
419
369
  const clientSocket = new net.Socket();
420
- clientSocket.on('error', (clientError) => {
421
- if (clientError.code === 'ECONNREFUSED') {
370
+
371
+ clientSocket.on('error', (err) => {
372
+ if (err.code === 'ECONNREFUSED') {
422
373
  // No other server listening on this socket so it can be safely removed
423
374
  fs.unlinkSync(options.socket);
424
- server.listen(options.socket, options.host, (err) => {
425
- if (err) throw err;
375
+
376
+ server.listen(options.socket, options.host, (error) => {
377
+ if (error) {
378
+ throw error;
379
+ }
426
380
  });
427
381
  }
428
382
  });
383
+
429
384
  clientSocket.connect({ path: options.socket }, () => {
430
385
  throw new Error('This socket is already used');
431
386
  });
432
387
  }
433
388
  });
389
+
434
390
  server.listen(options.socket, options.host, (err) => {
435
- if (err) throw err;
391
+ if (err) {
392
+ throw err;
393
+ }
436
394
  // chmod 666 (rw rw rw)
437
395
  const READ_WRITE = 438;
438
- fs.chmod(options.socket, READ_WRITE, (fsError) => {
439
- if (fsError) throw fsError;
396
+
397
+ fs.chmod(options.socket, READ_WRITE, (err) => {
398
+ if (err) {
399
+ throw err;
400
+ }
440
401
 
441
402
  const uri = createDomain(options, server.listeningApp) + suffix;
442
- reportReadiness(uri, options, log);
403
+
404
+ status(uri, options, log, argv.color);
443
405
  });
444
406
  });
445
407
  } else {
446
408
  server.listen(options.port, options.host, (err) => {
447
- if (err) throw err;
448
- if (options.bonjour) broadcastZeroconf(options);
449
-
450
- const uri = createDomain(options, server.listeningApp) + suffix;
451
- reportReadiness(uri, options, log);
452
- });
453
- }
454
- }
455
-
456
- function reportReadiness(uri, options, log) {
457
- const useColor = argv.color;
458
- const contentBase = Array.isArray(options.contentBase) ? options.contentBase.join(', ') : options.contentBase;
459
-
460
- if (options.socket) {
461
- log.info(`Listening to socket at ${colorInfo(useColor, options.socket)}`);
462
- } else {
463
- log.info(`Project is running at ${colorInfo(useColor, uri)}`);
464
- }
465
-
466
- log.info(`webpack output is served from ${colorInfo(useColor, options.publicPath)}`);
467
-
468
- if (contentBase) { log.info(`Content not from webpack is served from ${colorInfo(useColor, contentBase)}`); }
469
-
470
- if (options.historyApiFallback) { log.info(`404s will fallback to ${colorInfo(useColor, options.historyApiFallback.index || '/index.html')}`); }
471
-
472
- if (options.bonjour) { log.info('Broadcasting "http" with subtype of "webpack" via ZeroConf DNS (Bonjour)'); }
409
+ if (err) {
410
+ throw err;
411
+ }
473
412
 
474
- if (options.open) {
475
- let openOptions = {};
476
- let openMessage = 'Unable to open browser';
413
+ if (options.bonjour) {
414
+ bonjour(options);
415
+ }
477
416
 
478
- if (typeof options.open === 'string') {
479
- openOptions = { app: options.open };
480
- openMessage += `: ${options.open}`;
481
- }
417
+ const uri = createDomain(options, server.listeningApp) + suffix;
482
418
 
483
- open(uri + (options.openPage || ''), openOptions).catch(() => {
484
- log.warn(`${openMessage}. If you are running in a headless environment, please do not use the open flag.`);
419
+ status(uri, options, log, argv.color);
485
420
  });
486
421
  }
487
422
  }
488
423
 
489
- function broadcastZeroconf(options) {
490
- const bonjour = require('bonjour')();
491
- bonjour.publish({
492
- name: 'Webpack Dev Server',
493
- port: options.port,
494
- type: 'http',
495
- subtypes: ['webpack']
496
- });
497
- process.on('exit', () => {
498
- bonjour.unpublishAll(() => {
499
- bonjour.destroy();
500
- });
501
- });
502
- }
503
-
504
- processOptions(wpOpt);
424
+ processOptions(config);