webpack-dev-server 4.15.0 → 5.0.0

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.
package/lib/Server.js CHANGED
@@ -37,18 +37,19 @@ const schema = require("./options.json");
37
37
  /** @typedef {import("ipaddr.js").IPv6} IPv6 */
38
38
  /** @typedef {import("net").Socket} Socket */
39
39
  /** @typedef {import("http").IncomingMessage} IncomingMessage */
40
+ /** @typedef {import("http").ServerResponse} ServerResponse */
40
41
  /** @typedef {import("open").Options} OpenOptions */
41
42
 
42
43
  /** @typedef {import("https").ServerOptions & { spdy?: { plain?: boolean | undefined, ssl?: boolean | undefined, 'x-forwarded-for'?: string | undefined, protocol?: string | undefined, protocols?: string[] | undefined }}} ServerOptions */
43
44
 
44
45
  /**
45
46
  * @template Request, Response
46
- * @typedef {import("webpack-dev-middleware").Options<Request, Response>} DevMiddlewareOptions
47
+ * @typedef {import("webpack-dev-middleware").Options<IncomingMessage, ServerResponse>} DevMiddlewareOptions
47
48
  */
48
49
 
49
50
  /**
50
51
  * @template Request, Response
51
- * @typedef {import("webpack-dev-middleware").Context<Request, Response>} DevMiddlewareContext
52
+ * @typedef {import("webpack-dev-middleware").Context<IncomingMessage, ServerResponse>} DevMiddlewareContext
52
53
  */
53
54
 
54
55
  /**
@@ -185,7 +186,6 @@ const schema = require("./options.json");
185
186
  * @property {boolean} [liveReload]
186
187
  * @property {DevMiddlewareOptions<Request, Response>} [devMiddleware]
187
188
  * @property {boolean} [compress]
188
- * @property {boolean} [magicHtml]
189
189
  * @property {"auto" | "all" | string | string[]} [allowedHosts]
190
190
  * @property {boolean | ConnectHistoryApiFallbackOptions} [historyApiFallback]
191
191
  * @property {boolean | Record<string, never> | BonjourOptions} [bonjour]
@@ -200,16 +200,12 @@ const schema = require("./options.json");
200
200
  * @property {boolean} [setupExitSignals]
201
201
  * @property {boolean | ClientConfiguration} [client]
202
202
  * @property {Headers | ((req: Request, res: Response, context: DevMiddlewareContext<Request, Response>) => Headers)} [headers]
203
- * @property {(devServer: Server) => void} [onAfterSetupMiddleware]
204
- * @property {(devServer: Server) => void} [onBeforeSetupMiddleware]
205
203
  * @property {(devServer: Server) => void} [onListening]
206
204
  * @property {(middlewares: Middleware[], devServer: Server) => Middleware[]} [setupMiddlewares]
207
205
  */
208
206
 
209
207
  if (!process.env.WEBPACK_SERVE) {
210
- // TODO fix me in the next major release
211
- // @ts-ignore
212
- process.env.WEBPACK_SERVE = true;
208
+ process.env.WEBPACK_SERVE = "true";
213
209
  }
214
210
 
215
211
  /**
@@ -256,17 +252,6 @@ class Server {
256
252
  * @param {Compiler | MultiCompiler | Configuration} compiler
257
253
  */
258
254
  constructor(options = {}, compiler) {
259
- // TODO: remove this after plugin support is published
260
- if (/** @type {Compiler | MultiCompiler} */ (options).hooks) {
261
- util.deprecate(
262
- () => {},
263
- "Using 'compiler' as the first argument is deprecated. Please use 'options' as the first argument and 'compiler' as the second argument.",
264
- "DEP_WEBPACK_DEV_SERVER_CONSTRUCTOR"
265
- )();
266
-
267
- [options = {}, compiler] = [compiler, options];
268
- }
269
-
270
255
  validate(/** @type {Schema} */ (schema), options, {
271
256
  name: "Dev Server",
272
257
  baseDataPath: "options",
@@ -305,18 +290,6 @@ class Server {
305
290
  this.currentHash = undefined;
306
291
  }
307
292
 
308
- // TODO compatibility with webpack v4, remove it after drop
309
- static get cli() {
310
- return {
311
- get getArguments() {
312
- return () => require("../bin/cli-flags");
313
- },
314
- get processArguments() {
315
- return require("../bin/process-arguments");
316
- },
317
- };
318
- }
319
-
320
293
  static get schema() {
321
294
  return schema;
322
295
  }
@@ -383,6 +356,7 @@ class Server {
383
356
  static async internalIP(family) {
384
357
  try {
385
358
  const { gateway } = await require("default-gateway")[family]();
359
+
386
360
  return Server.findIp(gateway);
387
361
  } catch {
388
362
  // ignore
@@ -396,6 +370,7 @@ class Server {
396
370
  static internalIPSync(family) {
397
371
  try {
398
372
  const { gateway } = require("default-gateway")[family].sync();
373
+
399
374
  return Server.findIp(gateway);
400
375
  } catch {
401
376
  // ignore
@@ -432,7 +407,7 @@ class Server {
432
407
  return port;
433
408
  }
434
409
 
435
- const pRetry = require("p-retry");
410
+ const pRetry = (await import("p-retry")).default;
436
411
  const getPort = require("./getPort");
437
412
  const basePort =
438
413
  typeof process.env.WEBPACK_DEV_SERVER_BASE_PORT !== "undefined"
@@ -582,18 +557,27 @@ class Server {
582
557
  let hostname;
583
558
 
584
559
  // SockJS is not supported server mode, so `hostname` and `port` can't specified, let's ignore them
585
- // TODO show warning about this
586
560
  const isSockJSType = webSocketServer.type === "sockjs";
561
+ const isWebSocketServerHostDefined =
562
+ typeof webSocketServer.options.host !== "undefined";
563
+ const isWebSocketServerPortDefined =
564
+ typeof webSocketServer.options.port !== "undefined";
565
+
566
+ if (
567
+ isSockJSType &&
568
+ (isWebSocketServerHostDefined || isWebSocketServerPortDefined)
569
+ ) {
570
+ this.logger.warn(
571
+ "SockJS only supports client mode and does not support custom hostname and port options. Please consider using 'ws' if you need to customize these options.",
572
+ );
573
+ }
587
574
 
588
575
  // We are proxying dev server and need to specify custom `hostname`
589
576
  if (typeof webSocketURL.hostname !== "undefined") {
590
577
  hostname = webSocketURL.hostname;
591
578
  }
592
579
  // Web socket server works on custom `hostname`, only for `ws` because `sock-js` is not support custom `hostname`
593
- else if (
594
- typeof webSocketServer.options.host !== "undefined" &&
595
- !isSockJSType
596
- ) {
580
+ else if (isWebSocketServerHostDefined && !isSockJSType) {
597
581
  hostname = webSocketServer.options.host;
598
582
  }
599
583
  // The `host` option is specified
@@ -615,10 +599,7 @@ class Server {
615
599
  port = webSocketURL.port;
616
600
  }
617
601
  // Web socket server works on custom `port`, only for `ws` because `sock-js` is not support custom `port`
618
- else if (
619
- typeof webSocketServer.options.port !== "undefined" &&
620
- !isSockJSType
621
- ) {
602
+ else if (isWebSocketServerPortDefined && !isSockJSType) {
622
603
  port = webSocketServer.options.port;
623
604
  }
624
605
  // The `port` option is specified
@@ -676,7 +657,7 @@ class Server {
676
657
  errors: encodeOverlaySettings(client.overlay.errors),
677
658
  warnings: encodeOverlaySettings(client.overlay.warnings),
678
659
  runtimeErrors: encodeOverlaySettings(
679
- client.overlay.runtimeErrors
660
+ client.overlay.runtimeErrors,
680
661
  ),
681
662
  });
682
663
 
@@ -688,7 +669,7 @@ class Server {
688
669
  "reconnect",
689
670
  typeof client.reconnect === "number"
690
671
  ? String(client.reconnect)
691
- : "10"
672
+ : "10",
692
673
  );
693
674
  }
694
675
 
@@ -704,7 +685,7 @@ class Server {
704
685
  }
705
686
 
706
687
  additionalEntries.push(
707
- `${require.resolve("../client/index.js")}?${webSocketURLStr}`
688
+ `${require.resolve("../client/index.js")}?${webSocketURLStr}`,
708
689
  );
709
690
  }
710
691
 
@@ -717,69 +698,11 @@ class Server {
717
698
  const webpack = compiler.webpack || require("webpack");
718
699
 
719
700
  // use a hook to add entries if available
720
- if (typeof webpack.EntryPlugin !== "undefined") {
721
- for (const additionalEntry of additionalEntries) {
722
- new webpack.EntryPlugin(compiler.context, additionalEntry, {
723
- // eslint-disable-next-line no-undefined
724
- name: undefined,
725
- }).apply(compiler);
726
- }
727
- }
728
- // TODO remove after drop webpack v4 support
729
- else {
730
- /**
731
- * prependEntry Method for webpack 4
732
- * @param {any} originalEntry
733
- * @param {any} newAdditionalEntries
734
- * @returns {any}
735
- */
736
- const prependEntry = (originalEntry, newAdditionalEntries) => {
737
- if (typeof originalEntry === "function") {
738
- return () =>
739
- Promise.resolve(originalEntry()).then((entry) =>
740
- prependEntry(entry, newAdditionalEntries)
741
- );
742
- }
743
-
744
- if (
745
- typeof originalEntry === "object" &&
746
- !Array.isArray(originalEntry)
747
- ) {
748
- /** @type {Object<string,string>} */
749
- const clone = {};
750
-
751
- Object.keys(originalEntry).forEach((key) => {
752
- // entry[key] should be a string here
753
- const entryDescription = originalEntry[key];
754
-
755
- clone[key] = prependEntry(entryDescription, newAdditionalEntries);
756
- });
757
-
758
- return clone;
759
- }
760
-
761
- // in this case, entry is a string or an array.
762
- // make sure that we do not add duplicates.
763
- /** @type {any} */
764
- const entriesClone = additionalEntries.slice(0);
765
-
766
- [].concat(originalEntry).forEach((newEntry) => {
767
- if (!entriesClone.includes(newEntry)) {
768
- entriesClone.push(newEntry);
769
- }
770
- });
771
-
772
- return entriesClone;
773
- };
774
-
775
- compiler.options.entry = prependEntry(
776
- compiler.options.entry || "./src",
777
- additionalEntries
778
- );
779
- compiler.hooks.entryOption.call(
780
- /** @type {string} */ (compiler.options.context),
781
- compiler.options.entry
782
- );
701
+ for (const additionalEntry of additionalEntries) {
702
+ new webpack.EntryPlugin(compiler.context, additionalEntry, {
703
+ // eslint-disable-next-line no-undefined
704
+ name: undefined,
705
+ }).apply(compiler);
783
706
  }
784
707
  }
785
708
 
@@ -824,7 +747,7 @@ class Server {
824
747
  // eslint-disable-next-line no-undefined
825
748
  undefined,
826
749
  null,
827
- ].includes(/** @type {string} */ (config.options.target))
750
+ ].includes(/** @type {string} */ (config.options.target)),
828
751
  );
829
752
 
830
753
  if (compilerWithWebPreset) {
@@ -845,8 +768,7 @@ class Server {
845
768
  async normalizeOptions() {
846
769
  const { options } = this;
847
770
  const compilerOptions = this.getCompilerOptions();
848
- // TODO remove `{}` after drop webpack v4 support
849
- const compilerWatchOptions = compilerOptions.watchOptions || {};
771
+ const compilerWatchOptions = compilerOptions.watchOptions;
850
772
  /**
851
773
  * @param {WatchOptions & { aggregateTimeout?: number, ignored?: WatchOptions["ignored"], poll?: number | boolean }} watchOptions
852
774
  * @returns {WatchOptions}
@@ -933,10 +855,9 @@ class Server {
933
855
  typeof optionsForStatic.directory !== "undefined"
934
856
  ? optionsForStatic.directory
935
857
  : def.directory,
936
- // TODO: do merge in the next major release
937
858
  staticOptions:
938
859
  typeof optionsForStatic.staticOptions !== "undefined"
939
- ? optionsForStatic.staticOptions
860
+ ? { ...def.staticOptions, ...optionsForStatic.staticOptions }
940
861
  : def.staticOptions,
941
862
  publicPath:
942
863
  // eslint-disable-next-line no-nested-ternary
@@ -945,14 +866,21 @@ class Server {
945
866
  ? optionsForStatic.publicPath
946
867
  : [optionsForStatic.publicPath]
947
868
  : def.publicPath,
948
- // TODO: do merge in the next major release
949
869
  serveIndex:
870
+ // Check if 'serveIndex' property is defined in 'optionsForStatic'
871
+ // If 'serveIndex' is a boolean and true, use default 'serveIndex'
872
+ // If 'serveIndex' is an object, merge its properties with default 'serveIndex'
873
+ // If 'serveIndex' is neither a boolean true nor an object, use it as-is
874
+ // If 'serveIndex' is not defined in 'optionsForStatic', use default 'serveIndex'
950
875
  // eslint-disable-next-line no-nested-ternary
951
876
  typeof optionsForStatic.serveIndex !== "undefined"
952
- ? typeof optionsForStatic.serveIndex === "boolean" &&
877
+ ? // eslint-disable-next-line no-nested-ternary
878
+ typeof optionsForStatic.serveIndex === "boolean" &&
953
879
  optionsForStatic.serveIndex
954
880
  ? def.serveIndex
955
- : optionsForStatic.serveIndex
881
+ : typeof optionsForStatic.serveIndex === "object"
882
+ ? { ...def.serveIndex, ...optionsForStatic.serveIndex }
883
+ : optionsForStatic.serveIndex
956
884
  : def.serveIndex,
957
885
  watch:
958
886
  // eslint-disable-next-line no-nested-ternary
@@ -1023,7 +951,7 @@ class Server {
1023
951
  };
1024
952
  } else if (typeof options.client.webSocketURL.port === "string") {
1025
953
  options.client.webSocketURL.port = Number(
1026
- options.client.webSocketURL.port
954
+ options.client.webSocketURL.port,
1027
955
  );
1028
956
  }
1029
957
 
@@ -1080,41 +1008,14 @@ class Server {
1080
1008
  ? options.hot
1081
1009
  : true;
1082
1010
 
1083
- const isHTTPs = Boolean(options.https);
1084
- const isSPDY = Boolean(options.http2);
1085
-
1086
- if (isHTTPs) {
1087
- // TODO: remove in the next major release
1088
- util.deprecate(
1089
- () => {},
1090
- "'https' option is deprecated. Please use the 'server' option.",
1091
- "DEP_WEBPACK_DEV_SERVER_HTTPS"
1092
- )();
1093
- }
1094
-
1095
- if (isSPDY) {
1096
- // TODO: remove in the next major release
1097
- util.deprecate(
1098
- () => {},
1099
- "'http2' option is deprecated. Please use the 'server' option.",
1100
- "DEP_WEBPACK_DEV_SERVER_HTTP2"
1101
- )();
1102
- }
1103
-
1104
1011
  options.server = {
1105
1012
  type:
1106
1013
  // eslint-disable-next-line no-nested-ternary
1107
1014
  typeof options.server === "string"
1108
1015
  ? options.server
1109
- : // eslint-disable-next-line no-nested-ternary
1110
- typeof (options.server || {}).type === "string"
1111
- ? /** @type {ServerConfiguration} */ (options.server).type || "http"
1112
- : // eslint-disable-next-line no-nested-ternary
1113
- isSPDY
1114
- ? "spdy"
1115
- : isHTTPs
1116
- ? "https"
1117
- : "http",
1016
+ : typeof (options.server || {}).type === "string"
1017
+ ? /** @type {ServerConfiguration} */ (options.server).type || "http"
1018
+ : "http",
1118
1019
  options: {
1119
1020
  .../** @type {ServerOptions} */ (options.https),
1120
1021
  .../** @type {ServerConfiguration} */ (options.server || {}).options,
@@ -1144,7 +1045,7 @@ class Server {
1144
1045
 
1145
1046
  const httpsProperties =
1146
1047
  /** @type {Array<keyof ServerOptions>} */
1147
- (["cacert", "ca", "cert", "crl", "key", "pfx"]);
1048
+ (["ca", "cert", "crl", "key", "pfx"]);
1148
1049
 
1149
1050
  for (const property of httpsProperties) {
1150
1051
  if (
@@ -1156,16 +1057,6 @@ class Server {
1156
1057
  continue;
1157
1058
  }
1158
1059
 
1159
- // @ts-ignore
1160
- if (property === "cacert") {
1161
- // TODO remove the `cacert` option in favor `ca` in the next major release
1162
- util.deprecate(
1163
- () => {},
1164
- "The 'cacert' option is deprecated. Please use the 'ca' option.",
1165
- "DEP_WEBPACK_DEV_SERVER_CACERT"
1166
- )();
1167
- }
1168
-
1169
1060
  /** @type {any} */
1170
1061
  const value =
1171
1062
  /** @type {ServerOptions} */
@@ -1226,15 +1117,13 @@ class Server {
1226
1117
 
1227
1118
  // cert is more than 30 days old, kill it with fire
1228
1119
  if ((now - Number(certificateStat.ctime)) / certificateTtl > 30) {
1229
- const { promisify } = require("util");
1230
- const rimraf = require("rimraf");
1231
- const del = promisify(rimraf);
1120
+ const { rimraf } = require("rimraf");
1232
1121
 
1233
1122
  this.logger.info(
1234
- "SSL certificate is more than 30 days old. Removing..."
1123
+ "SSL certificate is more than 30 days old. Removing...",
1235
1124
  );
1236
1125
 
1237
- await del(certificatePath);
1126
+ await rimraf(certificatePath);
1238
1127
 
1239
1128
  certificateExists = false;
1240
1129
  }
@@ -1315,7 +1204,7 @@ class Server {
1315
1204
  pems.private + pems.cert,
1316
1205
  {
1317
1206
  encoding: "utf8",
1318
- }
1207
+ },
1319
1208
  );
1320
1209
  }
1321
1210
 
@@ -1324,29 +1213,6 @@ class Server {
1324
1213
  this.logger.info(`SSL certificate: ${certificatePath}`);
1325
1214
  }
1326
1215
 
1327
- if (
1328
- /** @type {ServerOptions & { cacert?: ServerOptions["ca"] }} */ (
1329
- options.server.options
1330
- ).cacert
1331
- ) {
1332
- if (/** @type {ServerOptions} */ (options.server.options).ca) {
1333
- this.logger.warn(
1334
- "Do not specify 'ca' and 'cacert' options together, the 'ca' option will be used."
1335
- );
1336
- } else {
1337
- /** @type {ServerOptions} */
1338
- (options.server.options).ca =
1339
- /** @type {ServerOptions & { cacert?: ServerOptions["ca"] }} */
1340
- (options.server.options).cacert;
1341
- }
1342
-
1343
- delete (
1344
- /** @type {ServerOptions & { cacert?: ServerOptions["ca"] }} */ (
1345
- options.server.options
1346
- ).cacert
1347
- );
1348
- }
1349
-
1350
1216
  /** @type {ServerOptions} */
1351
1217
  (options.server.options).key =
1352
1218
  /** @type {ServerOptions} */
@@ -1368,16 +1234,12 @@ class Server {
1368
1234
  options.liveReload =
1369
1235
  typeof options.liveReload !== "undefined" ? options.liveReload : true;
1370
1236
 
1371
- options.magicHtml =
1372
- typeof options.magicHtml !== "undefined" ? options.magicHtml : true;
1373
-
1374
1237
  // https://github.com/webpack/webpack-dev-server/issues/1990
1375
1238
  const defaultOpenOptions = { wait: false };
1376
1239
  /**
1377
1240
  * @param {any} target
1378
1241
  * @returns {NormalizedOpen[]}
1379
1242
  */
1380
- // TODO: remove --open-app in favor of --open-app-name
1381
1243
  const getOpenItemsFromObject = ({ target, ...rest }) => {
1382
1244
  const normalizedOptions = { ...defaultOpenOptions, ...rest };
1383
1245
 
@@ -1437,24 +1299,6 @@ class Server {
1437
1299
  (options.open) = [...getOpenItemsFromObject(options.open)];
1438
1300
  }
1439
1301
 
1440
- if (options.onAfterSetupMiddleware) {
1441
- // TODO: remove in the next major release
1442
- util.deprecate(
1443
- () => {},
1444
- "'onAfterSetupMiddleware' option is deprecated. Please use the 'setupMiddlewares' option.",
1445
- `DEP_WEBPACK_DEV_SERVER_ON_AFTER_SETUP_MIDDLEWARE`
1446
- )();
1447
- }
1448
-
1449
- if (options.onBeforeSetupMiddleware) {
1450
- // TODO: remove in the next major release
1451
- util.deprecate(
1452
- () => {},
1453
- "'onBeforeSetupMiddleware' option is deprecated. Please use the 'setupMiddlewares' option.",
1454
- `DEP_WEBPACK_DEV_SERVER_ON_BEFORE_SETUP_MIDDLEWARE`
1455
- )();
1456
- }
1457
-
1458
1302
  if (typeof options.port === "string" && options.port !== "auto") {
1459
1303
  options.port = Number(options.port);
1460
1304
  }
@@ -1470,53 +1314,6 @@ class Server {
1470
1314
  * }
1471
1315
  */
1472
1316
  if (typeof options.proxy !== "undefined") {
1473
- // TODO remove in the next major release, only accept `Array`
1474
- if (!Array.isArray(options.proxy)) {
1475
- if (
1476
- Object.prototype.hasOwnProperty.call(options.proxy, "target") ||
1477
- Object.prototype.hasOwnProperty.call(options.proxy, "router")
1478
- ) {
1479
- /** @type {ProxyConfigArray} */
1480
- (options.proxy) = [/** @type {ProxyConfigMap} */ (options.proxy)];
1481
- } else {
1482
- /** @type {ProxyConfigArray} */
1483
- (options.proxy) = Object.keys(options.proxy).map(
1484
- /**
1485
- * @param {string} context
1486
- * @returns {HttpProxyMiddlewareOptions}
1487
- */
1488
- (context) => {
1489
- let proxyOptions;
1490
- // For backwards compatibility reasons.
1491
- const correctedContext = context
1492
- .replace(/^\*$/, "**")
1493
- .replace(/\/\*$/, "");
1494
-
1495
- if (
1496
- typeof (
1497
- /** @type {ProxyConfigMap} */ (options.proxy)[context]
1498
- ) === "string"
1499
- ) {
1500
- proxyOptions = {
1501
- context: correctedContext,
1502
- target:
1503
- /** @type {ProxyConfigMap} */
1504
- (options.proxy)[context],
1505
- };
1506
- } else {
1507
- proxyOptions = {
1508
- // @ts-ignore
1509
- .../** @type {ProxyConfigMap} */ (options.proxy)[context],
1510
- };
1511
- proxyOptions.context = correctedContext;
1512
- }
1513
-
1514
- return proxyOptions;
1515
- }
1516
- );
1517
- }
1518
- }
1519
-
1520
1317
  /** @type {ProxyConfigArray} */
1521
1318
  (options.proxy) =
1522
1319
  /** @type {ProxyConfigArray} */
@@ -1549,7 +1346,7 @@ class Server {
1549
1346
  item.logLevel = getLogLevelForProxy(
1550
1347
  compilerOptions.infrastructureLogging
1551
1348
  ? compilerOptions.infrastructureLogging.level
1552
- : "info"
1349
+ : "info",
1553
1350
  );
1554
1351
  }
1555
1352
 
@@ -1697,11 +1494,11 @@ class Server {
1697
1494
  // could be 'sockjs', 'ws', or a path that should be required
1698
1495
  if (clientTransport === "sockjs") {
1699
1496
  clientImplementation = require.resolve(
1700
- "../client/clients/SockJSClient"
1497
+ "../client/clients/SockJSClient",
1701
1498
  );
1702
1499
  } else if (clientTransport === "ws") {
1703
1500
  clientImplementation = require.resolve(
1704
- "../client/clients/WebSocketClient"
1501
+ "../client/clients/WebSocketClient",
1705
1502
  );
1706
1503
  } else {
1707
1504
  try {
@@ -1721,7 +1518,7 @@ class Server {
1721
1518
  !isKnownWebSocketServerImplementation
1722
1519
  ? "When you use custom web socket implementation you must explicitly specify client.webSocketTransport. "
1723
1520
  : ""
1724
- }client.webSocketTransport must be a string denoting a default implementation (e.g. 'sockjs', 'ws') or a full path to a JS file via require.resolve(...) which exports a class `
1521
+ }client.webSocketTransport must be a string denoting a default implementation (e.g. 'sockjs', 'ws') or a full path to a JS file via require.resolve(...) which exports a class `,
1725
1522
  );
1726
1523
  }
1727
1524
 
@@ -1759,9 +1556,11 @@ class Server {
1759
1556
  } else {
1760
1557
  try {
1761
1558
  // eslint-disable-next-line import/no-dynamic-require
1762
- implementation = require(/** @type {WebSocketServerConfiguration} */ (
1763
- this.options.webSocketServer
1764
- ).type);
1559
+ implementation = require(
1560
+ /** @type {WebSocketServerConfiguration} */ (
1561
+ this.options.webSocketServer
1562
+ ).type,
1563
+ );
1765
1564
  } catch (error) {
1766
1565
  implementationFound = false;
1767
1566
  }
@@ -1780,7 +1579,7 @@ class Server {
1780
1579
  throw new Error(
1781
1580
  "webSocketServer (webSocketServer.type) must be a string denoting a default implementation (e.g. 'ws', 'sockjs'), a full path to " +
1782
1581
  "a JS file which exports a class extending BaseServer (webpack-dev-server/lib/servers/BaseServer.js) " +
1783
- "via require.resolve(...), or the class itself which extends BaseServer"
1582
+ "via require.resolve(...), or the class itself which extends BaseServer",
1784
1583
  );
1785
1584
  }
1786
1585
 
@@ -1796,9 +1595,7 @@ class Server {
1796
1595
  /** @type {MultiCompiler}*/
1797
1596
  (this.compiler).compilers
1798
1597
  ? /** @type {MultiCompiler}*/ (this.compiler).compilers[0].webpack
1799
- : /** @type {Compiler}*/ (this.compiler).webpack ||
1800
- // TODO remove me after drop webpack v4
1801
- require("webpack");
1598
+ : /** @type {Compiler}*/ (this.compiler).webpack;
1802
1599
 
1803
1600
  new ProgressPlugin(
1804
1601
  /**
@@ -1829,7 +1626,7 @@ class Server {
1829
1626
  if (this.server) {
1830
1627
  this.server.emit("progress-update", { percent, msg, pluginName });
1831
1628
  }
1832
- }
1629
+ },
1833
1630
  ).apply(this.compiler);
1834
1631
  }
1835
1632
 
@@ -1852,17 +1649,14 @@ class Server {
1852
1649
  __webpack_dev_server_client__: this.getClientTransport(),
1853
1650
  }).apply(compiler);
1854
1651
 
1855
- // TODO remove after drop webpack v4 support
1856
- compiler.options.plugins = compiler.options.plugins || [];
1857
-
1858
1652
  if (this.options.hot) {
1859
1653
  const HMRPluginExists = compiler.options.plugins.find(
1860
- (p) => p.constructor === webpack.HotModuleReplacementPlugin
1654
+ (p) => p && p.constructor === webpack.HotModuleReplacementPlugin,
1861
1655
  );
1862
1656
 
1863
1657
  if (HMRPluginExists) {
1864
1658
  this.logger.warn(
1865
- `"hot: true" automatically applies HMR plugin, you don't have to add it manually to your webpack configuration.`
1659
+ `"hot: true" automatically applies HMR plugin, you don't have to add it manually to your webpack configuration.`,
1866
1660
  );
1867
1661
  } else {
1868
1662
  // Apply the HMR plugin
@@ -1904,7 +1698,7 @@ class Server {
1904
1698
  }
1905
1699
 
1906
1700
  this.logger.info(
1907
- "Gracefully shutting down. To force exit, press ^C again. Please wait..."
1701
+ "Gracefully shutting down. To force exit, press ^C again. Please wait...",
1908
1702
  );
1909
1703
 
1910
1704
  needForceShutdown = true;
@@ -1934,7 +1728,7 @@ class Server {
1934
1728
  (this.server).on(
1935
1729
  "upgrade",
1936
1730
  /** @type {RequestHandler & { upgrade: NonNullable<RequestHandler["upgrade"]> }} */
1937
- (webSocketProxy).upgrade
1731
+ (webSocketProxy).upgrade,
1938
1732
  );
1939
1733
  }, this);
1940
1734
  }
@@ -1991,7 +1785,7 @@ class Server {
1991
1785
  * @type {Stats | MultiStats}
1992
1786
  */
1993
1787
  this.stats = stats;
1994
- }
1788
+ },
1995
1789
  );
1996
1790
  }
1997
1791
 
@@ -2014,14 +1808,14 @@ class Server {
2014
1808
  this.checkHeader(
2015
1809
  /** @type {{ [key: string]: string | undefined }} */
2016
1810
  (req.headers),
2017
- "host"
1811
+ "host",
2018
1812
  )
2019
1813
  ) {
2020
1814
  return next();
2021
1815
  }
2022
1816
 
2023
1817
  res.send("Invalid Host header");
2024
- }
1818
+ },
2025
1819
  );
2026
1820
  }
2027
1821
 
@@ -2035,7 +1829,7 @@ class Server {
2035
1829
  // middleware for serving webpack bundle
2036
1830
  this.middleware = webpackDevMiddleware(
2037
1831
  this.compiler,
2038
- this.options.devMiddleware
1832
+ this.options.devMiddleware,
2039
1833
  );
2040
1834
  }
2041
1835
 
@@ -2060,7 +1854,7 @@ class Server {
2060
1854
  const clientPath = path.join(__dirname, "..", "client");
2061
1855
 
2062
1856
  res.sendFile(path.join(clientPath, "modules/sockjs-client/index.js"));
2063
- }
1857
+ },
2064
1858
  );
2065
1859
 
2066
1860
  /** @type {import("express").Application} */
@@ -2075,7 +1869,7 @@ class Server {
2075
1869
  this.invalidate();
2076
1870
 
2077
1871
  res.end();
2078
- }
1872
+ },
2079
1873
  );
2080
1874
 
2081
1875
  /** @type {import("express").Application} */
@@ -2103,8 +1897,13 @@ class Server {
2103
1897
  /** @type {import("webpack-dev-middleware").API<Request, Response>}*/
2104
1898
  (middleware).waitUntilValid((stats) => {
2105
1899
  res.setHeader("Content-Type", "text/html");
1900
+ // HEAD requests should not return body content
1901
+ if (req.method === "HEAD") {
1902
+ res.end();
1903
+ return;
1904
+ }
2106
1905
  res.write(
2107
- '<!DOCTYPE html><html><head><meta charset="utf-8"/></head><body>'
1906
+ '<!DOCTYPE html><html><head><meta charset="utf-8"/></head><body>',
2108
1907
  );
2109
1908
 
2110
1909
  const statsForPrint =
@@ -2125,8 +1924,8 @@ class Server {
2125
1924
  typeof item.name !== "undefined"
2126
1925
  ? item.name
2127
1926
  : /** @type {MultiStats} */ (stats).stats
2128
- ? `unnamed[${index}]`
2129
- : "unnamed";
1927
+ ? `unnamed[${index}]`
1928
+ : "unnamed";
2130
1929
 
2131
1930
  res.write(`<h2>Compilation: ${name}</h2>`);
2132
1931
  res.write("<ul>");
@@ -2143,7 +1942,7 @@ class Server {
2143
1942
  res.write(
2144
1943
  `<li>
2145
1944
  <strong><a href="${assetURL}" target="_blank">${assetName}</a></strong>
2146
- </li>`
1945
+ </li>`,
2147
1946
  );
2148
1947
  }
2149
1948
 
@@ -2153,7 +1952,7 @@ class Server {
2153
1952
 
2154
1953
  res.end("</body></html>");
2155
1954
  });
2156
- }
1955
+ },
2157
1956
  );
2158
1957
  }
2159
1958
 
@@ -2204,10 +2003,6 @@ class Server {
2204
2003
  middlewares.push({ name: "compression", middleware: compression() });
2205
2004
  }
2206
2005
 
2207
- if (typeof this.options.onBeforeSetupMiddleware === "function") {
2208
- this.options.onBeforeSetupMiddleware(this);
2209
- }
2210
-
2211
2006
  if (typeof this.options.headers !== "undefined") {
2212
2007
  middlewares.push({
2213
2008
  name: "set-headers",
@@ -2238,13 +2033,22 @@ class Server {
2238
2033
 
2239
2034
  return createProxyMiddleware(
2240
2035
  /** @type {string} */ (context),
2241
- proxyConfig
2036
+ proxyConfig,
2242
2037
  );
2243
2038
  }
2244
2039
 
2245
2040
  if (proxyConfig.router) {
2246
2041
  return createProxyMiddleware(proxyConfig);
2247
2042
  }
2043
+
2044
+ // TODO improve me after drop `bypass` to always generate error when configuration is bad
2045
+ if (!proxyConfig.bypass) {
2046
+ util.deprecate(
2047
+ () => {},
2048
+ `Invalid proxy configuration:\n\n${JSON.stringify(proxyConfig, null, 2)}\n\nThe use of proxy object notation as proxy routes has been removed.\nPlease use the 'router' or 'context' options. Read more at https://github.com/chimurai/http-proxy-middleware/tree/v2.0.6#http-proxy-middleware-options`,
2049
+ "DEP_WEBPACK_DEV_SERVER_PROXY_ROUTES_ARGUMENT",
2050
+ )();
2051
+ }
2248
2052
  };
2249
2053
 
2250
2054
  /**
@@ -2295,6 +2099,15 @@ class Server {
2295
2099
 
2296
2100
  if (newProxyConfig !== proxyConfig) {
2297
2101
  proxyConfig = newProxyConfig;
2102
+
2103
+ const socket = req.socket != null ? req.socket : req.connection;
2104
+ // @ts-ignore
2105
+ const server = socket != null ? socket.server : null;
2106
+
2107
+ if (server) {
2108
+ server.removeAllListeners("close");
2109
+ }
2110
+
2298
2111
  proxyMiddleware =
2299
2112
  /** @type {RequestHandler} */
2300
2113
  (getProxyMiddleware(proxyConfig));
@@ -2306,11 +2119,18 @@ class Server {
2306
2119
  // bypassUrl from it otherwise bypassUrl would be null
2307
2120
  // TODO remove in the next major in favor `context` and `router` options
2308
2121
  const isByPassFuncDefined = typeof proxyConfig.bypass === "function";
2122
+ if (isByPassFuncDefined) {
2123
+ util.deprecate(
2124
+ () => {},
2125
+ "Using the 'bypass' option is deprecated. Please use the 'router' or 'context' options. Read more at https://github.com/chimurai/http-proxy-middleware/tree/v2.0.6#http-proxy-middleware-options",
2126
+ "DEP_WEBPACK_DEV_SERVER_PROXY_BYPASS_ARGUMENT",
2127
+ )();
2128
+ }
2309
2129
  const bypassUrl = isByPassFuncDefined
2310
2130
  ? await /** @type {ByPass} */ (proxyConfig.bypass)(
2311
2131
  req,
2312
2132
  res,
2313
- proxyConfig
2133
+ proxyConfig,
2314
2134
  )
2315
2135
  : null;
2316
2136
 
@@ -2366,7 +2186,7 @@ class Server {
2366
2186
  path: publicPath,
2367
2187
  middleware: getExpress().static(
2368
2188
  staticOption.directory,
2369
- staticOption.staticOptions
2189
+ staticOption.staticOptions,
2370
2190
  ),
2371
2191
  });
2372
2192
  });
@@ -2390,7 +2210,7 @@ class Server {
2390
2210
  // @ts-ignore
2391
2211
  historyApiFallback.logger = this.logger.log.bind(
2392
2212
  this.logger,
2393
- "[connect-history-api-fallback]"
2213
+ "[connect-history-api-fallback]",
2394
2214
  );
2395
2215
  }
2396
2216
 
@@ -2399,7 +2219,7 @@ class Server {
2399
2219
  name: "connect-history-api-fallback",
2400
2220
  middleware: connectHistoryApiFallback(
2401
2221
  /** @type {ConnectHistoryApiFallbackOptions} */
2402
- (historyApiFallback)
2222
+ (historyApiFallback),
2403
2223
  ),
2404
2224
  });
2405
2225
 
@@ -2421,7 +2241,7 @@ class Server {
2421
2241
  path: publicPath,
2422
2242
  middleware: getExpress().static(
2423
2243
  staticOption.directory,
2424
- staticOption.staticOptions
2244
+ staticOption.staticOptions,
2425
2245
  ),
2426
2246
  });
2427
2247
  });
@@ -2454,7 +2274,7 @@ class Server {
2454
2274
  serveIndex(
2455
2275
  staticOption.directory,
2456
2276
  /** @type {ServeIndexOptions} */
2457
- (staticOption.serveIndex)
2277
+ (staticOption.serveIndex),
2458
2278
  )(req, res, next);
2459
2279
  },
2460
2280
  });
@@ -2463,13 +2283,6 @@ class Server {
2463
2283
  });
2464
2284
  }
2465
2285
 
2466
- if (this.options.magicHtml) {
2467
- middlewares.push({
2468
- name: "serve-magic-html",
2469
- middleware: this.serveMagicHtml.bind(this),
2470
- });
2471
- }
2472
-
2473
2286
  // Register this middleware always as the last one so that it's only used as a
2474
2287
  // fallback when no other middleware responses.
2475
2288
  middlewares.push({
@@ -2508,10 +2321,6 @@ class Server {
2508
2321
  (this.app).use(middleware.middleware);
2509
2322
  }
2510
2323
  });
2511
-
2512
- if (typeof this.options.onAfterSetupMiddleware === "function") {
2513
- this.options.onAfterSetupMiddleware(this);
2514
- }
2515
2324
  }
2516
2325
 
2517
2326
  /**
@@ -2527,7 +2336,7 @@ class Server {
2527
2336
  // eslint-disable-next-line import/no-dynamic-require
2528
2337
  this.server = require(/** @type {string} */ (type)).createServer(
2529
2338
  options,
2530
- this.app
2339
+ this.app,
2531
2340
  );
2532
2341
 
2533
2342
  /** @type {import("http").Server} */
@@ -2544,7 +2353,7 @@ class Server {
2544
2353
  // Remove socket from list
2545
2354
  this.sockets.splice(this.sockets.indexOf(socket), 1);
2546
2355
  });
2547
- }
2356
+ },
2548
2357
  );
2549
2358
 
2550
2359
  /** @type {import("http").Server} */
@@ -2555,7 +2364,7 @@ class Server {
2555
2364
  */
2556
2365
  (error) => {
2557
2366
  throw error;
2558
- }
2367
+ },
2559
2368
  );
2560
2369
  }
2561
2370
 
@@ -2563,11 +2372,10 @@ class Server {
2563
2372
  * @private
2564
2373
  * @returns {void}
2565
2374
  */
2566
- // TODO: remove `--web-socket-server` in favor of `--web-socket-server-type`
2567
2375
  createWebSocketServer() {
2568
2376
  /** @type {WebSocketServerImplementation | undefined | null} */
2569
2377
  this.webSocketServer = new /** @type {any} */ (this.getServerTransport())(
2570
- this
2378
+ this,
2571
2379
  );
2572
2380
  /** @type {WebSocketServerImplementation} */
2573
2381
  (this.webSocketServer).implementation.on(
@@ -2584,15 +2392,15 @@ class Server {
2584
2392
  ? /** @type {{ [key: string]: string | undefined }} */
2585
2393
  (request.headers)
2586
2394
  : typeof (
2587
- /** @type {import("sockjs").Connection} */ (client).headers
2588
- ) !== "undefined"
2589
- ? /** @type {import("sockjs").Connection} */ (client).headers
2590
- : // eslint-disable-next-line no-undefined
2591
- undefined;
2395
+ /** @type {import("sockjs").Connection} */ (client).headers
2396
+ ) !== "undefined"
2397
+ ? /** @type {import("sockjs").Connection} */ (client).headers
2398
+ : // eslint-disable-next-line no-undefined
2399
+ undefined;
2592
2400
 
2593
2401
  if (!headers) {
2594
2402
  this.logger.warn(
2595
- 'webSocketServer implementation must pass headers for the "connection" event'
2403
+ 'webSocketServer implementation must pass headers for the "connection" event',
2596
2404
  );
2597
2405
  }
2598
2406
 
@@ -2627,7 +2435,7 @@ class Server {
2627
2435
  [client],
2628
2436
  "progress",
2629
2437
  /** @type {ClientConfiguration} */
2630
- (this.options.client).progress
2438
+ (this.options.client).progress,
2631
2439
  );
2632
2440
  }
2633
2441
 
@@ -2639,7 +2447,7 @@ class Server {
2639
2447
  [client],
2640
2448
  "reconnect",
2641
2449
  /** @type {ClientConfiguration} */
2642
- (this.options.client).reconnect
2450
+ (this.options.client).reconnect,
2643
2451
  );
2644
2452
  }
2645
2453
 
@@ -2668,7 +2476,7 @@ class Server {
2668
2476
  overlayConfig.runtimeErrors &&
2669
2477
  encodeOverlaySettings(overlayConfig.runtimeErrors),
2670
2478
  }
2671
- : overlayConfig
2479
+ : overlayConfig,
2672
2480
  );
2673
2481
  }
2674
2482
 
@@ -2677,17 +2485,17 @@ class Server {
2677
2485
  }
2678
2486
 
2679
2487
  this.sendStats([client], this.getStats(this.stats), true);
2680
- }
2488
+ },
2681
2489
  );
2682
2490
  }
2683
2491
 
2684
2492
  /**
2685
2493
  * @private
2686
2494
  * @param {string} defaultOpenTarget
2687
- * @returns {void}
2495
+ * @returns {Promise<void>}
2688
2496
  */
2689
- openBrowser(defaultOpenTarget) {
2690
- const open = require("open");
2497
+ async openBrowser(defaultOpenTarget) {
2498
+ const open = (await import("open")).default;
2691
2499
 
2692
2500
  Promise.all(
2693
2501
  /** @type {NormalizedOpen[]} */
@@ -2722,10 +2530,10 @@ class Server {
2722
2530
  : ""
2723
2531
  }`
2724
2532
  : ""
2725
- }. If you are running in a headless environment, please do not use the "open" option or related flags like "--open", "--open-target", and "--open-app".`
2533
+ }. If you are running in a headless environment, please do not use the "open" option or related flags like "--open", "--open-target", and "--open-app-name".`,
2726
2534
  );
2727
2535
  });
2728
- })
2536
+ }),
2729
2537
  );
2730
2538
  }
2731
2539
 
@@ -2772,9 +2580,9 @@ class Server {
2772
2580
 
2773
2581
  /**
2774
2582
  * @private
2775
- * @returns {void}
2583
+ * @returns {Promise<void>}
2776
2584
  */
2777
- logStatus() {
2585
+ async logStatus() {
2778
2586
  const { isColorSupported, cyan, red } = require("colorette");
2779
2587
 
2780
2588
  /**
@@ -2835,7 +2643,7 @@ class Server {
2835
2643
  `Project is running at: "${
2836
2644
  /** @type {import("http").Server} */
2837
2645
  (this.server).address()
2838
- }"`
2646
+ }"`,
2839
2647
  );
2840
2648
  } else {
2841
2649
  const protocol =
@@ -2884,13 +2692,13 @@ class Server {
2884
2692
  if (parsedIP.range() === "unspecified") {
2885
2693
  localhost = prettyPrintURL("localhost");
2886
2694
 
2887
- const networkIPv4 = Server.internalIPSync("v4");
2695
+ const networkIPv4 = await Server.internalIP("v4");
2888
2696
 
2889
2697
  if (networkIPv4) {
2890
2698
  networkUrlIPv4 = prettyPrintURL(networkIPv4);
2891
2699
  }
2892
2700
 
2893
- const networkIPv6 = Server.internalIPSync("v6");
2701
+ const networkIPv6 = await Server.internalIP("v6");
2894
2702
 
2895
2703
  if (networkIPv6) {
2896
2704
  networkUrlIPv6 = prettyPrintURL(networkIPv6);
@@ -2908,7 +2716,7 @@ class Server {
2908
2716
  (parsedIP).isIPv4MappedAddress()
2909
2717
  ? prettyPrintURL(
2910
2718
  /** @type {IPv6} */
2911
- (parsedIP).toIPv4Address().toString()
2719
+ (parsedIP).toIPv4Address().toString(),
2912
2720
  )
2913
2721
  : prettyPrintURL(address);
2914
2722
 
@@ -2943,24 +2751,26 @@ class Server {
2943
2751
 
2944
2752
  if (networkUrlIPv4) {
2945
2753
  this.logger.info(
2946
- `On Your Network (IPv4): ${colors.info(useColor, networkUrlIPv4)}`
2754
+ `On Your Network (IPv4): ${colors.info(useColor, networkUrlIPv4)}`,
2947
2755
  );
2948
2756
  }
2949
2757
 
2950
2758
  if (networkUrlIPv6) {
2951
2759
  this.logger.info(
2952
- `On Your Network (IPv6): ${colors.info(useColor, networkUrlIPv6)}`
2760
+ `On Your Network (IPv6): ${colors.info(useColor, networkUrlIPv6)}`,
2953
2761
  );
2954
2762
  }
2955
2763
 
2956
2764
  if (/** @type {NormalizedOpen[]} */ (this.options.open).length > 0) {
2957
2765
  const openTarget = prettyPrintURL(
2958
- !this.options.host || this.options.host === "0.0.0.0"
2766
+ !this.options.host ||
2767
+ this.options.host === "0.0.0.0" ||
2768
+ this.options.host === "::"
2959
2769
  ? "localhost"
2960
- : this.options.host
2770
+ : this.options.host,
2961
2771
  );
2962
2772
 
2963
- this.openBrowser(openTarget);
2773
+ await this.openBrowser(openTarget);
2964
2774
  }
2965
2775
  }
2966
2776
 
@@ -2971,8 +2781,8 @@ class Server {
2971
2781
  /** @type {NormalizedStatic[]} */
2972
2782
  (this.options.static)
2973
2783
  .map((staticOption) => staticOption.directory)
2974
- .join(", ")
2975
- )}' directory`
2784
+ .join(", "),
2785
+ )}' directory`,
2976
2786
  );
2977
2787
  }
2978
2788
 
@@ -2982,8 +2792,8 @@ class Server {
2982
2792
  useColor,
2983
2793
  /** @type {ConnectHistoryApiFallbackOptions} */ (
2984
2794
  this.options.historyApiFallback
2985
- ).index || "/index.html"
2986
- )}'`
2795
+ ).index || "/index.html",
2796
+ )}'`,
2987
2797
  );
2988
2798
  }
2989
2799
 
@@ -2997,7 +2807,7 @@ class Server {
2997
2807
  : "https";
2998
2808
 
2999
2809
  this.logger.info(
3000
- `Broadcasting "${bonjourProtocol}" with subtype of "webpack" via ZeroConf DNS (Bonjour)`
2810
+ `Broadcasting "${bonjourProtocol}" with subtype of "webpack" via ZeroConf DNS (Bonjour)`,
3001
2811
  );
3002
2812
  }
3003
2813
  }
@@ -3016,8 +2826,8 @@ class Server {
3016
2826
  headers = headers(
3017
2827
  req,
3018
2828
  res,
3019
- /** @type {import("webpack-dev-middleware").API<Request, Response>}*/
3020
- (this.middleware).context
2829
+ /** @type {import("webpack-dev-middleware").API<IncomingMessage, ServerResponse>}*/
2830
+ (this.middleware).context,
3021
2831
  );
3022
2832
  }
3023
2833
 
@@ -3042,7 +2852,7 @@ class Server {
3042
2852
  */
3043
2853
  (header) => {
3044
2854
  res.setHeader(header.key, header.value);
3045
- }
2855
+ },
3046
2856
  );
3047
2857
  }
3048
2858
 
@@ -3079,7 +2889,7 @@ class Server {
3079
2889
  // if hostHeader doesn't have scheme, add // for parsing.
3080
2890
  /^(.+:)?\/\//.test(hostHeader) ? hostHeader : `//${hostHeader}`,
3081
2891
  false,
3082
- true
2892
+ true,
3083
2893
  ).hostname;
3084
2894
 
3085
2895
  // always allow requests with explicit IPv4 or IPv6-address.
@@ -3164,51 +2974,6 @@ class Server {
3164
2974
  }
3165
2975
  }
3166
2976
 
3167
- /**
3168
- * @private
3169
- * @param {Request} req
3170
- * @param {Response} res
3171
- * @param {NextFunction} next
3172
- * @returns {void}
3173
- */
3174
- serveMagicHtml(req, res, next) {
3175
- if (req.method !== "GET" && req.method !== "HEAD") {
3176
- return next();
3177
- }
3178
-
3179
- /** @type {import("webpack-dev-middleware").API<Request, Response>}*/
3180
- (this.middleware).waitUntilValid(() => {
3181
- const _path = req.path;
3182
-
3183
- try {
3184
- const filename =
3185
- /** @type {import("webpack-dev-middleware").API<Request, Response>}*/
3186
- (this.middleware).getFilenameFromUrl(`${_path}.js`);
3187
- const isFile =
3188
- /** @type {Compiler["outputFileSystem"] & { statSync: import("fs").StatSyncFn }}*/
3189
- (
3190
- /** @type {import("webpack-dev-middleware").API<Request, Response>}*/
3191
- (this.middleware).context.outputFileSystem
3192
- )
3193
- .statSync(/** @type {import("fs").PathLike} */ (filename))
3194
- .isFile();
3195
-
3196
- if (!isFile) {
3197
- return next();
3198
- }
3199
-
3200
- // Serve a page that executes the javascript
3201
- // @ts-ignore
3202
- const queries = req._parsedUrl.search || "";
3203
- const responsePage = `<!DOCTYPE html><html><head><meta charset="utf-8"/></head><body><script type="text/javascript" charset="utf-8" src="${_path}.js${queries}"></script></body></html>`;
3204
-
3205
- res.send(responsePage);
3206
- } catch (error) {
3207
- return next();
3208
- }
3209
- });
3210
- }
3211
-
3212
2977
  // Send stats to a socket or multiple sockets
3213
2978
  /**
3214
2979
  * @private
@@ -3282,7 +3047,7 @@ class Server {
3282
3047
  this.sendMessage(
3283
3048
  this.webSocketServer.clients,
3284
3049
  "static-changed",
3285
- item
3050
+ item,
3286
3051
  );
3287
3052
  }
3288
3053
  });
@@ -3332,24 +3097,24 @@ class Server {
3332
3097
  }
3333
3098
 
3334
3099
  reject(error);
3335
- }
3100
+ },
3336
3101
  );
3337
3102
 
3338
3103
  socket.connect(
3339
3104
  { path: /** @type {string} */ (this.options.ipc) },
3340
3105
  () => {
3341
3106
  throw new Error(`IPC "${this.options.ipc}" is already used`);
3342
- }
3107
+ },
3343
3108
  );
3344
3109
  })
3345
3110
  );
3346
3111
  } else {
3347
3112
  this.options.host = await Server.getHostname(
3348
- /** @type {Host} */ (this.options.host)
3113
+ /** @type {Host} */ (this.options.host),
3349
3114
  );
3350
3115
  this.options.port = await Server.getFreePort(
3351
3116
  /** @type {Port} */ (this.options.port),
3352
- this.options.host
3117
+ this.options.host,
3353
3118
  );
3354
3119
  }
3355
3120
 
@@ -3374,7 +3139,7 @@ class Server {
3374
3139
 
3375
3140
  await fs.promises.chmod(
3376
3141
  /** @type {string} */ (this.options.ipc),
3377
- READ_WRITE
3142
+ READ_WRITE,
3378
3143
  );
3379
3144
  }
3380
3145
 
@@ -3386,7 +3151,7 @@ class Server {
3386
3151
  this.runBonjour();
3387
3152
  }
3388
3153
 
3389
- this.logStatus();
3154
+ await this.logStatus();
3390
3155
 
3391
3156
  if (typeof this.options.onListening === "function") {
3392
3157
  this.options.onListening(this);
@@ -3497,95 +3262,6 @@ class Server {
3497
3262
  .then(() => callback(), callback)
3498
3263
  .catch(callback);
3499
3264
  }
3500
-
3501
- // TODO remove in the next major release
3502
- /**
3503
- * @param {Port} port
3504
- * @param {Host} hostname
3505
- * @param {(err?: Error) => void} fn
3506
- * @returns {void}
3507
- */
3508
- listen(port, hostname, fn) {
3509
- util.deprecate(
3510
- () => {},
3511
- "'listen' is deprecated. Please use the async 'start' or 'startCallback' method.",
3512
- "DEP_WEBPACK_DEV_SERVER_LISTEN"
3513
- )();
3514
-
3515
- if (typeof port === "function") {
3516
- fn = port;
3517
- }
3518
-
3519
- if (
3520
- typeof port !== "undefined" &&
3521
- typeof this.options.port !== "undefined" &&
3522
- port !== this.options.port
3523
- ) {
3524
- this.options.port = port;
3525
-
3526
- this.logger.warn(
3527
- 'The "port" specified in options is different from the port passed as an argument. Will be used from arguments.'
3528
- );
3529
- }
3530
-
3531
- if (!this.options.port) {
3532
- this.options.port = port;
3533
- }
3534
-
3535
- if (
3536
- typeof hostname !== "undefined" &&
3537
- typeof this.options.host !== "undefined" &&
3538
- hostname !== this.options.host
3539
- ) {
3540
- this.options.host = hostname;
3541
-
3542
- this.logger.warn(
3543
- 'The "host" specified in options is different from the host passed as an argument. Will be used from arguments.'
3544
- );
3545
- }
3546
-
3547
- if (!this.options.host) {
3548
- this.options.host = hostname;
3549
- }
3550
-
3551
- this.start()
3552
- .then(() => {
3553
- if (fn) {
3554
- fn.call(this.server);
3555
- }
3556
- })
3557
- .catch((error) => {
3558
- // Nothing
3559
- if (fn) {
3560
- fn.call(this.server, error);
3561
- }
3562
- });
3563
- }
3564
-
3565
- /**
3566
- * @param {(err?: Error) => void} [callback]
3567
- * @returns {void}
3568
- */
3569
- // TODO remove in the next major release
3570
- close(callback) {
3571
- util.deprecate(
3572
- () => {},
3573
- "'close' is deprecated. Please use the async 'stop' or 'stopCallback' method.",
3574
- "DEP_WEBPACK_DEV_SERVER_CLOSE"
3575
- )();
3576
-
3577
- this.stop()
3578
- .then(() => {
3579
- if (callback) {
3580
- callback();
3581
- }
3582
- })
3583
- .catch((error) => {
3584
- if (callback) {
3585
- callback(error);
3586
- }
3587
- });
3588
- }
3589
3265
  }
3590
3266
 
3591
3267
  module.exports = Server;