webpack-dev-server 4.15.1 → 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/README.md +15 -34
- package/bin/webpack-dev-server.js +5 -5
- package/client/clients/SockJSClient.js +2 -2
- package/client/clients/WebSocketClient.js +2 -2
- package/client/index.js +5 -14
- package/client/modules/logger/index.js +2934 -54
- package/client/modules/sockjs-client/index.js +0 -5
- package/client/overlay/fsm.js +4 -4
- package/client/overlay.js +10 -10
- package/lib/Server.js +161 -487
- package/lib/getPort.js +2 -2
- package/lib/options.json +20 -270
- package/lib/servers/SockJSServer.js +2 -2
- package/lib/servers/WebsocketServer.js +15 -4
- package/package.json +59 -62
- package/types/lib/Server.d.ts +270 -2301
- package/types/lib/getPort.d.ts +1 -1
- package/bin/process-arguments.js +0 -412
- package/types/bin/process-arguments.d.ts +0 -50
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<
|
|
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<
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
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
|
-
|
|
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
|
-
?
|
|
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
|
-
:
|
|
1110
|
-
|
|
1111
|
-
|
|
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
|
-
(["
|
|
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 {
|
|
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
|
|
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(
|
|
1763
|
-
|
|
1764
|
-
|
|
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
|
-
|
|
2129
|
-
|
|
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
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
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 =
|
|
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.
|
|
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.
|
|
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,13 +2751,13 @@ 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
|
|
|
@@ -2959,10 +2767,10 @@ class Server {
|
|
|
2959
2767
|
this.options.host === "0.0.0.0" ||
|
|
2960
2768
|
this.options.host === "::"
|
|
2961
2769
|
? "localhost"
|
|
2962
|
-
: this.options.host
|
|
2770
|
+
: this.options.host,
|
|
2963
2771
|
);
|
|
2964
2772
|
|
|
2965
|
-
this.openBrowser(openTarget);
|
|
2773
|
+
await this.openBrowser(openTarget);
|
|
2966
2774
|
}
|
|
2967
2775
|
}
|
|
2968
2776
|
|
|
@@ -2973,8 +2781,8 @@ class Server {
|
|
|
2973
2781
|
/** @type {NormalizedStatic[]} */
|
|
2974
2782
|
(this.options.static)
|
|
2975
2783
|
.map((staticOption) => staticOption.directory)
|
|
2976
|
-
.join(", ")
|
|
2977
|
-
)}' directory
|
|
2784
|
+
.join(", "),
|
|
2785
|
+
)}' directory`,
|
|
2978
2786
|
);
|
|
2979
2787
|
}
|
|
2980
2788
|
|
|
@@ -2984,8 +2792,8 @@ class Server {
|
|
|
2984
2792
|
useColor,
|
|
2985
2793
|
/** @type {ConnectHistoryApiFallbackOptions} */ (
|
|
2986
2794
|
this.options.historyApiFallback
|
|
2987
|
-
).index || "/index.html"
|
|
2988
|
-
)}'
|
|
2795
|
+
).index || "/index.html",
|
|
2796
|
+
)}'`,
|
|
2989
2797
|
);
|
|
2990
2798
|
}
|
|
2991
2799
|
|
|
@@ -2999,7 +2807,7 @@ class Server {
|
|
|
2999
2807
|
: "https";
|
|
3000
2808
|
|
|
3001
2809
|
this.logger.info(
|
|
3002
|
-
`Broadcasting "${bonjourProtocol}" with subtype of "webpack" via ZeroConf DNS (Bonjour)
|
|
2810
|
+
`Broadcasting "${bonjourProtocol}" with subtype of "webpack" via ZeroConf DNS (Bonjour)`,
|
|
3003
2811
|
);
|
|
3004
2812
|
}
|
|
3005
2813
|
}
|
|
@@ -3018,8 +2826,8 @@ class Server {
|
|
|
3018
2826
|
headers = headers(
|
|
3019
2827
|
req,
|
|
3020
2828
|
res,
|
|
3021
|
-
/** @type {import("webpack-dev-middleware").API<
|
|
3022
|
-
(this.middleware).context
|
|
2829
|
+
/** @type {import("webpack-dev-middleware").API<IncomingMessage, ServerResponse>}*/
|
|
2830
|
+
(this.middleware).context,
|
|
3023
2831
|
);
|
|
3024
2832
|
}
|
|
3025
2833
|
|
|
@@ -3044,7 +2852,7 @@ class Server {
|
|
|
3044
2852
|
*/
|
|
3045
2853
|
(header) => {
|
|
3046
2854
|
res.setHeader(header.key, header.value);
|
|
3047
|
-
}
|
|
2855
|
+
},
|
|
3048
2856
|
);
|
|
3049
2857
|
}
|
|
3050
2858
|
|
|
@@ -3081,7 +2889,7 @@ class Server {
|
|
|
3081
2889
|
// if hostHeader doesn't have scheme, add // for parsing.
|
|
3082
2890
|
/^(.+:)?\/\//.test(hostHeader) ? hostHeader : `//${hostHeader}`,
|
|
3083
2891
|
false,
|
|
3084
|
-
true
|
|
2892
|
+
true,
|
|
3085
2893
|
).hostname;
|
|
3086
2894
|
|
|
3087
2895
|
// always allow requests with explicit IPv4 or IPv6-address.
|
|
@@ -3166,51 +2974,6 @@ class Server {
|
|
|
3166
2974
|
}
|
|
3167
2975
|
}
|
|
3168
2976
|
|
|
3169
|
-
/**
|
|
3170
|
-
* @private
|
|
3171
|
-
* @param {Request} req
|
|
3172
|
-
* @param {Response} res
|
|
3173
|
-
* @param {NextFunction} next
|
|
3174
|
-
* @returns {void}
|
|
3175
|
-
*/
|
|
3176
|
-
serveMagicHtml(req, res, next) {
|
|
3177
|
-
if (req.method !== "GET" && req.method !== "HEAD") {
|
|
3178
|
-
return next();
|
|
3179
|
-
}
|
|
3180
|
-
|
|
3181
|
-
/** @type {import("webpack-dev-middleware").API<Request, Response>}*/
|
|
3182
|
-
(this.middleware).waitUntilValid(() => {
|
|
3183
|
-
const _path = req.path;
|
|
3184
|
-
|
|
3185
|
-
try {
|
|
3186
|
-
const filename =
|
|
3187
|
-
/** @type {import("webpack-dev-middleware").API<Request, Response>}*/
|
|
3188
|
-
(this.middleware).getFilenameFromUrl(`${_path}.js`);
|
|
3189
|
-
const isFile =
|
|
3190
|
-
/** @type {Compiler["outputFileSystem"] & { statSync: import("fs").StatSyncFn }}*/
|
|
3191
|
-
(
|
|
3192
|
-
/** @type {import("webpack-dev-middleware").API<Request, Response>}*/
|
|
3193
|
-
(this.middleware).context.outputFileSystem
|
|
3194
|
-
)
|
|
3195
|
-
.statSync(/** @type {import("fs").PathLike} */ (filename))
|
|
3196
|
-
.isFile();
|
|
3197
|
-
|
|
3198
|
-
if (!isFile) {
|
|
3199
|
-
return next();
|
|
3200
|
-
}
|
|
3201
|
-
|
|
3202
|
-
// Serve a page that executes the javascript
|
|
3203
|
-
// @ts-ignore
|
|
3204
|
-
const queries = req._parsedUrl.search || "";
|
|
3205
|
-
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>`;
|
|
3206
|
-
|
|
3207
|
-
res.send(responsePage);
|
|
3208
|
-
} catch (error) {
|
|
3209
|
-
return next();
|
|
3210
|
-
}
|
|
3211
|
-
});
|
|
3212
|
-
}
|
|
3213
|
-
|
|
3214
2977
|
// Send stats to a socket or multiple sockets
|
|
3215
2978
|
/**
|
|
3216
2979
|
* @private
|
|
@@ -3284,7 +3047,7 @@ class Server {
|
|
|
3284
3047
|
this.sendMessage(
|
|
3285
3048
|
this.webSocketServer.clients,
|
|
3286
3049
|
"static-changed",
|
|
3287
|
-
item
|
|
3050
|
+
item,
|
|
3288
3051
|
);
|
|
3289
3052
|
}
|
|
3290
3053
|
});
|
|
@@ -3334,24 +3097,24 @@ class Server {
|
|
|
3334
3097
|
}
|
|
3335
3098
|
|
|
3336
3099
|
reject(error);
|
|
3337
|
-
}
|
|
3100
|
+
},
|
|
3338
3101
|
);
|
|
3339
3102
|
|
|
3340
3103
|
socket.connect(
|
|
3341
3104
|
{ path: /** @type {string} */ (this.options.ipc) },
|
|
3342
3105
|
() => {
|
|
3343
3106
|
throw new Error(`IPC "${this.options.ipc}" is already used`);
|
|
3344
|
-
}
|
|
3107
|
+
},
|
|
3345
3108
|
);
|
|
3346
3109
|
})
|
|
3347
3110
|
);
|
|
3348
3111
|
} else {
|
|
3349
3112
|
this.options.host = await Server.getHostname(
|
|
3350
|
-
/** @type {Host} */ (this.options.host)
|
|
3113
|
+
/** @type {Host} */ (this.options.host),
|
|
3351
3114
|
);
|
|
3352
3115
|
this.options.port = await Server.getFreePort(
|
|
3353
3116
|
/** @type {Port} */ (this.options.port),
|
|
3354
|
-
this.options.host
|
|
3117
|
+
this.options.host,
|
|
3355
3118
|
);
|
|
3356
3119
|
}
|
|
3357
3120
|
|
|
@@ -3376,7 +3139,7 @@ class Server {
|
|
|
3376
3139
|
|
|
3377
3140
|
await fs.promises.chmod(
|
|
3378
3141
|
/** @type {string} */ (this.options.ipc),
|
|
3379
|
-
READ_WRITE
|
|
3142
|
+
READ_WRITE,
|
|
3380
3143
|
);
|
|
3381
3144
|
}
|
|
3382
3145
|
|
|
@@ -3388,7 +3151,7 @@ class Server {
|
|
|
3388
3151
|
this.runBonjour();
|
|
3389
3152
|
}
|
|
3390
3153
|
|
|
3391
|
-
this.logStatus();
|
|
3154
|
+
await this.logStatus();
|
|
3392
3155
|
|
|
3393
3156
|
if (typeof this.options.onListening === "function") {
|
|
3394
3157
|
this.options.onListening(this);
|
|
@@ -3499,95 +3262,6 @@ class Server {
|
|
|
3499
3262
|
.then(() => callback(), callback)
|
|
3500
3263
|
.catch(callback);
|
|
3501
3264
|
}
|
|
3502
|
-
|
|
3503
|
-
// TODO remove in the next major release
|
|
3504
|
-
/**
|
|
3505
|
-
* @param {Port} port
|
|
3506
|
-
* @param {Host} hostname
|
|
3507
|
-
* @param {(err?: Error) => void} fn
|
|
3508
|
-
* @returns {void}
|
|
3509
|
-
*/
|
|
3510
|
-
listen(port, hostname, fn) {
|
|
3511
|
-
util.deprecate(
|
|
3512
|
-
() => {},
|
|
3513
|
-
"'listen' is deprecated. Please use the async 'start' or 'startCallback' method.",
|
|
3514
|
-
"DEP_WEBPACK_DEV_SERVER_LISTEN"
|
|
3515
|
-
)();
|
|
3516
|
-
|
|
3517
|
-
if (typeof port === "function") {
|
|
3518
|
-
fn = port;
|
|
3519
|
-
}
|
|
3520
|
-
|
|
3521
|
-
if (
|
|
3522
|
-
typeof port !== "undefined" &&
|
|
3523
|
-
typeof this.options.port !== "undefined" &&
|
|
3524
|
-
port !== this.options.port
|
|
3525
|
-
) {
|
|
3526
|
-
this.options.port = port;
|
|
3527
|
-
|
|
3528
|
-
this.logger.warn(
|
|
3529
|
-
'The "port" specified in options is different from the port passed as an argument. Will be used from arguments.'
|
|
3530
|
-
);
|
|
3531
|
-
}
|
|
3532
|
-
|
|
3533
|
-
if (!this.options.port) {
|
|
3534
|
-
this.options.port = port;
|
|
3535
|
-
}
|
|
3536
|
-
|
|
3537
|
-
if (
|
|
3538
|
-
typeof hostname !== "undefined" &&
|
|
3539
|
-
typeof this.options.host !== "undefined" &&
|
|
3540
|
-
hostname !== this.options.host
|
|
3541
|
-
) {
|
|
3542
|
-
this.options.host = hostname;
|
|
3543
|
-
|
|
3544
|
-
this.logger.warn(
|
|
3545
|
-
'The "host" specified in options is different from the host passed as an argument. Will be used from arguments.'
|
|
3546
|
-
);
|
|
3547
|
-
}
|
|
3548
|
-
|
|
3549
|
-
if (!this.options.host) {
|
|
3550
|
-
this.options.host = hostname;
|
|
3551
|
-
}
|
|
3552
|
-
|
|
3553
|
-
this.start()
|
|
3554
|
-
.then(() => {
|
|
3555
|
-
if (fn) {
|
|
3556
|
-
fn.call(this.server);
|
|
3557
|
-
}
|
|
3558
|
-
})
|
|
3559
|
-
.catch((error) => {
|
|
3560
|
-
// Nothing
|
|
3561
|
-
if (fn) {
|
|
3562
|
-
fn.call(this.server, error);
|
|
3563
|
-
}
|
|
3564
|
-
});
|
|
3565
|
-
}
|
|
3566
|
-
|
|
3567
|
-
/**
|
|
3568
|
-
* @param {(err?: Error) => void} [callback]
|
|
3569
|
-
* @returns {void}
|
|
3570
|
-
*/
|
|
3571
|
-
// TODO remove in the next major release
|
|
3572
|
-
close(callback) {
|
|
3573
|
-
util.deprecate(
|
|
3574
|
-
() => {},
|
|
3575
|
-
"'close' is deprecated. Please use the async 'stop' or 'stopCallback' method.",
|
|
3576
|
-
"DEP_WEBPACK_DEV_SERVER_CLOSE"
|
|
3577
|
-
)();
|
|
3578
|
-
|
|
3579
|
-
this.stop()
|
|
3580
|
-
.then(() => {
|
|
3581
|
-
if (callback) {
|
|
3582
|
-
callback();
|
|
3583
|
-
}
|
|
3584
|
-
})
|
|
3585
|
-
.catch((error) => {
|
|
3586
|
-
if (callback) {
|
|
3587
|
-
callback(error);
|
|
3588
|
-
}
|
|
3589
|
-
});
|
|
3590
|
-
}
|
|
3591
3265
|
}
|
|
3592
3266
|
|
|
3593
3267
|
module.exports = Server;
|