webpack-dev-server 4.7.2 → 4.8.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/client/socket.js CHANGED
@@ -9,8 +9,11 @@ typeof __webpack_dev_server_client__ !== "undefined" ? typeof __webpack_dev_serv
9
9
  /* eslint-enable camelcase */
10
10
 
11
11
  var retries = 0;
12
- var maxRetries = 10;
13
- var client = null;
12
+ var maxRetries = 10; // Initialized client is exported so external consumers can utilize the same instance
13
+ // It is mutable to enforce singleton
14
+ // eslint-disable-next-line import/no-mutable-exports
15
+
16
+ export var client = null;
14
17
  /**
15
18
  * @param {string} url
16
19
  * @param {{ [handler: string]: (data?: any, params?: any) => any }} handlers
@@ -5,7 +5,7 @@
5
5
  function format(objURL) {
6
6
  var protocol = objURL.protocol || "";
7
7
 
8
- if (protocol && protocol.substr(-1) !== ":") {
8
+ if (protocol && !protocol.endsWith(":")) {
9
9
  protocol += ":";
10
10
  }
11
11
 
@@ -9,7 +9,7 @@ function parseURL(resourceQuery) {
9
9
  var options = {};
10
10
 
11
11
  if (typeof resourceQuery === "string" && resourceQuery !== "") {
12
- var searchParams = resourceQuery.substr(1).split("&");
12
+ var searchParams = resourceQuery.slice(1).split("&");
13
13
 
14
14
  for (var i = 0; i < searchParams.length; i++) {
15
15
  var pair = searchParams[i].split("=");
@@ -0,0 +1,20 @@
1
+ var ansiRegex = new RegExp(["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)", "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|"), "g");
2
+ /**
3
+ *
4
+ * Strip [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) from a string.
5
+ * Adapted from code originally released by Sindre Sorhus
6
+ * Licensed the MIT License
7
+ *
8
+ * @param {string} string
9
+ * @return {string}
10
+ */
11
+
12
+ function stripAnsi(string) {
13
+ if (typeof string !== "string") {
14
+ throw new TypeError("Expected a `string`, got `".concat(typeof string, "`"));
15
+ }
16
+
17
+ return string.replace(ansiRegex, "");
18
+ }
19
+
20
+ export default stripAnsi;
package/lib/Server.js CHANGED
@@ -25,11 +25,12 @@ const schema = require("./options.json");
25
25
  /** @typedef {import("express").NextFunction} NextFunction */
26
26
  /** @typedef {import("express").RequestHandler} ExpressRequestHandler */
27
27
  /** @typedef {import("express").ErrorRequestHandler} ExpressErrorRequestHandler */
28
+ /** @typedef {import("anymatch").Matcher} AnymatchMatcher */
28
29
  /** @typedef {import("chokidar").WatchOptions} WatchOptions */
29
30
  /** @typedef {import("chokidar").FSWatcher} FSWatcher */
30
31
  /** @typedef {import("connect-history-api-fallback").Options} ConnectHistoryApiFallbackOptions */
31
- /** @typedef {import("bonjour").Bonjour} Bonjour */
32
- /** @typedef {import("bonjour").BonjourOptions} BonjourOptions */
32
+ /** @typedef {import("bonjour-service").Bonjour} Bonjour */
33
+ /** @typedef {import("bonjour-service").Service} BonjourOptions */
33
34
  /** @typedef {import("http-proxy-middleware").RequestHandler} RequestHandler */
34
35
  /** @typedef {import("http-proxy-middleware").Options} HttpProxyMiddlewareOptions */
35
36
  /** @typedef {import("http-proxy-middleware").Filter} HttpProxyMiddlewareOptionsFilter */
@@ -64,7 +65,7 @@ const schema = require("./options.json");
64
65
  /**
65
66
  * @typedef {Object} WatchFiles
66
67
  * @property {string | string[]} paths
67
- * @property {WatchOptions & { aggregateTimeout?: number, ignored?: string | RegExp | string[], poll?: number | boolean }} [options]
68
+ * @property {WatchOptions & { aggregateTimeout?: number, ignored?: AnymatchMatcher | string[], poll?: number | boolean }} [options]
68
69
  */
69
70
 
70
71
  /**
@@ -73,7 +74,7 @@ const schema = require("./options.json");
73
74
  * @property {string | string[]} [publicPath]
74
75
  * @property {boolean | ServeIndexOptions} [serveIndex]
75
76
  * @property {ServeStaticOptions} [staticOptions]
76
- * @property {boolean | WatchOptions & { aggregateTimeout?: number, ignored?: string | RegExp | string[], poll?: number | boolean }} [watch]
77
+ * @property {boolean | WatchOptions & { aggregateTimeout?: number, ignored?: AnymatchMatcher | string[], poll?: number | boolean }} [watch]
77
78
  */
78
79
 
79
80
  /**
@@ -110,22 +111,22 @@ const schema = require("./options.json");
110
111
  */
111
112
 
112
113
  /**
113
- * @typedef {{ [url: string]: string | HttpProxyMiddlewareOptions }} ProxyConfigMap
114
+ * @callback ByPass
115
+ * @param {Request} req
116
+ * @param {Response} res
117
+ * @param {ProxyConfigArrayItem} proxyConfig
114
118
  */
115
119
 
116
120
  /**
117
- * @typedef {HttpProxyMiddlewareOptions[]} ProxyArray
121
+ * @typedef {{ path?: HttpProxyMiddlewareOptionsFilter | undefined, context?: HttpProxyMiddlewareOptionsFilter | undefined } & { bypass?: ByPass } & HttpProxyMiddlewareOptions } ProxyConfigArrayItem
118
122
  */
119
123
 
120
124
  /**
121
- * @callback ByPass
122
- * @param {Request} req
123
- * @param {Response} res
124
- * @param {ProxyConfigArray} proxyConfig
125
+ * @typedef {(ProxyConfigArrayItem | ((req?: Request | undefined, res?: Response | undefined, next?: NextFunction | undefined) => ProxyConfigArrayItem))[]} ProxyConfigArray
125
126
  */
126
127
 
127
128
  /**
128
- * @typedef {{ path?: string | string[] | undefined, context?: string | string[] | HttpProxyMiddlewareOptionsFilter | undefined } & HttpProxyMiddlewareOptions & ByPass} ProxyConfigArray
129
+ * @typedef {{ [url: string]: string | ProxyConfigArrayItem }} ProxyConfigMap
129
130
  */
130
131
 
131
132
  /**
@@ -187,14 +188,14 @@ const schema = require("./options.json");
187
188
  * @property {"auto" | "all" | string | string[]} [allowedHosts]
188
189
  * @property {boolean | ConnectHistoryApiFallbackOptions} [historyApiFallback]
189
190
  * @property {boolean} [setupExitSignals]
190
- * @property {boolean | BonjourOptions} [bonjour]
191
+ * @property {boolean | Record<string, never> | BonjourOptions} [bonjour]
191
192
  * @property {string | string[] | WatchFiles | Array<string | WatchFiles>} [watchFiles]
192
193
  * @property {boolean | string | Static | Array<string | Static>} [static]
193
194
  * @property {boolean | ServerOptions} [https]
194
195
  * @property {boolean} [http2]
195
196
  * @property {"http" | "https" | "spdy" | string | ServerConfiguration} [server]
196
197
  * @property {boolean | "sockjs" | "ws" | string | WebSocketServerConfiguration} [webSocketServer]
197
- * @property {ProxyConfigMap | ProxyConfigArray | ProxyArray} [proxy]
198
+ * @property {ProxyConfigMap | ProxyConfigArrayItem | ProxyConfigArray} [proxy]
198
199
  * @property {boolean | string | Open | Array<string | Open>} [open]
199
200
  * @property {boolean} [setupExitSignals]
200
201
  * @property {boolean | ClientConfiguration} [client]
@@ -754,7 +755,7 @@ class Server {
754
755
  // TODO remove `{}` after drop webpack v4 support
755
756
  const compilerWatchOptions = compilerOptions.watchOptions || {};
756
757
  /**
757
- * @param {WatchOptions & WebpackConfiguration["watchOptions"]} watchOptions
758
+ * @param {WatchOptions & { aggregateTimeout?: number, ignored?: AnymatchMatcher | string[], poll?: number | boolean }} watchOptions
758
759
  * @returns {WatchOptions}
759
760
  */
760
761
  const getWatchOptions = (watchOptions = {}) => {
@@ -1132,13 +1133,15 @@ class Server {
1132
1133
 
1133
1134
  // cert is more than 30 days old, kill it with fire
1134
1135
  if ((now - Number(certificateStat.ctime)) / certificateTtl > 30) {
1135
- const del = require("del");
1136
+ const { promisify } = require("util");
1137
+ const rimraf = require("rimraf");
1138
+ const del = promisify(rimraf);
1136
1139
 
1137
1140
  this.logger.info(
1138
1141
  "SSL certificate is more than 30 days old. Removing..."
1139
1142
  );
1140
1143
 
1141
- await del([certificatePath], { force: true });
1144
+ await del(certificatePath);
1142
1145
 
1143
1146
  certificateExists = false;
1144
1147
  }
@@ -1380,10 +1383,10 @@ class Server {
1380
1383
  Object.prototype.hasOwnProperty.call(options.proxy, "target") ||
1381
1384
  Object.prototype.hasOwnProperty.call(options.proxy, "router")
1382
1385
  ) {
1383
- /** @type {ProxyArray} */
1386
+ /** @type {ProxyConfigArray} */
1384
1387
  (options.proxy) = [/** @type {ProxyConfigMap} */ (options.proxy)];
1385
1388
  } else {
1386
- /** @type {ProxyArray} */
1389
+ /** @type {ProxyConfigArray} */
1387
1390
  (options.proxy) = Object.keys(options.proxy).map(
1388
1391
  /**
1389
1392
  * @param {string} context
@@ -1421,50 +1424,48 @@ class Server {
1421
1424
  }
1422
1425
  }
1423
1426
 
1424
- /** @type {ProxyArray} */
1427
+ /** @type {ProxyConfigArray} */
1425
1428
  (options.proxy) =
1426
- /** @type {ProxyArray} */
1427
- (options.proxy).map(
1429
+ /** @type {ProxyConfigArray} */
1430
+ (options.proxy).map((item) => {
1431
+ if (typeof item === "function") {
1432
+ return item;
1433
+ }
1434
+
1428
1435
  /**
1429
- * @param {HttpProxyMiddlewareOptions} item
1430
- * @returns {HttpProxyMiddlewareOptions}
1436
+ * @param {"info" | "warn" | "error" | "debug" | "silent" | undefined | "none" | "log" | "verbose"} level
1437
+ * @returns {"info" | "warn" | "error" | "debug" | "silent" | undefined}
1431
1438
  */
1432
- (item) => {
1433
- /**
1434
- * @param {"info" | "warn" | "error" | "debug" | "silent" | undefined | "none" | "log" | "verbose"} level
1435
- * @returns {"info" | "warn" | "error" | "debug" | "silent" | undefined}
1436
- */
1437
- const getLogLevelForProxy = (level) => {
1438
- if (level === "none") {
1439
- return "silent";
1440
- }
1441
-
1442
- if (level === "log") {
1443
- return "info";
1444
- }
1445
-
1446
- if (level === "verbose") {
1447
- return "debug";
1448
- }
1449
-
1450
- return level;
1451
- };
1439
+ const getLogLevelForProxy = (level) => {
1440
+ if (level === "none") {
1441
+ return "silent";
1442
+ }
1452
1443
 
1453
- if (typeof item.logLevel === "undefined") {
1454
- item.logLevel = getLogLevelForProxy(
1455
- compilerOptions.infrastructureLogging
1456
- ? compilerOptions.infrastructureLogging.level
1457
- : "info"
1458
- );
1444
+ if (level === "log") {
1445
+ return "info";
1459
1446
  }
1460
1447
 
1461
- if (typeof item.logProvider === "undefined") {
1462
- item.logProvider = () => this.logger;
1448
+ if (level === "verbose") {
1449
+ return "debug";
1463
1450
  }
1464
1451
 
1465
- return item;
1452
+ return level;
1453
+ };
1454
+
1455
+ if (typeof item.logLevel === "undefined") {
1456
+ item.logLevel = getLogLevelForProxy(
1457
+ compilerOptions.infrastructureLogging
1458
+ ? compilerOptions.infrastructureLogging.level
1459
+ : "info"
1460
+ );
1466
1461
  }
1467
- );
1462
+
1463
+ if (typeof item.logProvider === "undefined") {
1464
+ item.logProvider = () => this.logger;
1465
+ }
1466
+
1467
+ return item;
1468
+ });
1468
1469
  }
1469
1470
 
1470
1471
  if (typeof options.setupExitSignals === "undefined") {
@@ -1478,13 +1479,7 @@ class Server {
1478
1479
  } else if (typeof options.static === "string") {
1479
1480
  options.static = [getStaticItem(options.static)];
1480
1481
  } else if (Array.isArray(options.static)) {
1481
- options.static = options.static.map((item) => {
1482
- if (typeof item === "string") {
1483
- return getStaticItem(item);
1484
- }
1485
-
1486
- return getStaticItem(item);
1487
- });
1482
+ options.static = options.static.map((item) => getStaticItem(item));
1488
1483
  } else {
1489
1484
  options.static = [getStaticItem(options.static)];
1490
1485
  }
@@ -2130,7 +2125,7 @@ class Server {
2130
2125
  const { createProxyMiddleware } = require("http-proxy-middleware");
2131
2126
 
2132
2127
  /**
2133
- * @param {ProxyConfigArray} proxyConfig
2128
+ * @param {ProxyConfigArrayItem} proxyConfig
2134
2129
  * @returns {RequestHandler | undefined}
2135
2130
  */
2136
2131
  const getProxyMiddleware = (proxyConfig) => {
@@ -2166,93 +2161,91 @@ class Server {
2166
2161
  * }
2167
2162
  * ]
2168
2163
  */
2169
- /** @type {ProxyArray} */
2170
- (this.options.proxy).forEach(
2164
+ /** @type {ProxyConfigArray} */
2165
+ (this.options.proxy).forEach((proxyConfigOrCallback) => {
2171
2166
  /**
2172
- * @param {any} proxyConfigOrCallback
2167
+ * @type {RequestHandler}
2173
2168
  */
2174
- (proxyConfigOrCallback) => {
2175
- /**
2176
- * @type {RequestHandler}
2177
- */
2178
- let proxyMiddleware;
2169
+ let proxyMiddleware;
2179
2170
 
2180
- let proxyConfig =
2181
- typeof proxyConfigOrCallback === "function"
2182
- ? proxyConfigOrCallback()
2183
- : proxyConfigOrCallback;
2171
+ let proxyConfig =
2172
+ typeof proxyConfigOrCallback === "function"
2173
+ ? proxyConfigOrCallback()
2174
+ : proxyConfigOrCallback;
2184
2175
 
2185
- proxyMiddleware =
2186
- /** @type {RequestHandler} */
2187
- (getProxyMiddleware(proxyConfig));
2176
+ proxyMiddleware =
2177
+ /** @type {RequestHandler} */
2178
+ (getProxyMiddleware(proxyConfig));
2188
2179
 
2189
- if (proxyConfig.ws) {
2190
- this.webSocketProxies.push(proxyMiddleware);
2191
- }
2180
+ if (proxyConfig.ws) {
2181
+ this.webSocketProxies.push(proxyMiddleware);
2182
+ }
2192
2183
 
2193
- /**
2194
- * @param {Request} req
2195
- * @param {Response} res
2196
- * @param {NextFunction} next
2197
- * @returns {Promise<void>}
2198
- */
2199
- const handler = async (req, res, next) => {
2200
- if (typeof proxyConfigOrCallback === "function") {
2201
- const newProxyConfig = proxyConfigOrCallback(req, res, next);
2202
-
2203
- if (newProxyConfig !== proxyConfig) {
2204
- proxyConfig = newProxyConfig;
2205
- proxyMiddleware =
2206
- /** @type {RequestHandler} */
2207
- (getProxyMiddleware(proxyConfig));
2208
- }
2184
+ /**
2185
+ * @param {Request} req
2186
+ * @param {Response} res
2187
+ * @param {NextFunction} next
2188
+ * @returns {Promise<void>}
2189
+ */
2190
+ const handler = async (req, res, next) => {
2191
+ if (typeof proxyConfigOrCallback === "function") {
2192
+ const newProxyConfig = proxyConfigOrCallback(req, res, next);
2193
+
2194
+ if (newProxyConfig !== proxyConfig) {
2195
+ proxyConfig = newProxyConfig;
2196
+ proxyMiddleware =
2197
+ /** @type {RequestHandler} */
2198
+ (getProxyMiddleware(proxyConfig));
2209
2199
  }
2200
+ }
2210
2201
 
2211
- // - Check if we have a bypass function defined
2212
- // - In case the bypass function is defined we'll retrieve the
2213
- // bypassUrl from it otherwise bypassUrl would be null
2214
- // TODO remove in the next major in favor `context` and `router` options
2215
- const isByPassFuncDefined =
2216
- typeof proxyConfig.bypass === "function";
2217
- const bypassUrl = isByPassFuncDefined
2218
- ? await proxyConfig.bypass(req, res, proxyConfig)
2219
- : null;
2220
-
2221
- if (typeof bypassUrl === "boolean") {
2222
- // skip the proxy
2223
- // @ts-ignore
2224
- req.url = null;
2225
- next();
2226
- } else if (typeof bypassUrl === "string") {
2227
- // byPass to that url
2228
- req.url = bypassUrl;
2229
- next();
2230
- } else if (proxyMiddleware) {
2231
- return proxyMiddleware(req, res, next);
2232
- } else {
2233
- next();
2234
- }
2235
- };
2202
+ // - Check if we have a bypass function defined
2203
+ // - In case the bypass function is defined we'll retrieve the
2204
+ // bypassUrl from it otherwise bypassUrl would be null
2205
+ // TODO remove in the next major in favor `context` and `router` options
2206
+ const isByPassFuncDefined = typeof proxyConfig.bypass === "function";
2207
+ const bypassUrl = isByPassFuncDefined
2208
+ ? await /** @type {ByPass} */ (proxyConfig.bypass)(
2209
+ req,
2210
+ res,
2211
+ proxyConfig
2212
+ )
2213
+ : null;
2214
+
2215
+ if (typeof bypassUrl === "boolean") {
2216
+ // skip the proxy
2217
+ // @ts-ignore
2218
+ req.url = null;
2219
+ next();
2220
+ } else if (typeof bypassUrl === "string") {
2221
+ // byPass to that url
2222
+ req.url = bypassUrl;
2223
+ next();
2224
+ } else if (proxyMiddleware) {
2225
+ return proxyMiddleware(req, res, next);
2226
+ } else {
2227
+ next();
2228
+ }
2229
+ };
2236
2230
 
2237
- middlewares.push({
2238
- name: "http-proxy-middleware",
2239
- middleware: handler,
2240
- });
2241
- // Also forward error requests to the proxy so it can handle them.
2242
- middlewares.push({
2243
- name: "http-proxy-middleware-error-handler",
2244
- middleware:
2245
- /**
2246
- * @param {Error} error
2247
- * @param {Request} req
2248
- * @param {Response} res
2249
- * @param {NextFunction} next
2250
- * @returns {any}
2251
- */
2252
- (error, req, res, next) => handler(req, res, next),
2253
- });
2254
- }
2255
- );
2231
+ middlewares.push({
2232
+ name: "http-proxy-middleware",
2233
+ middleware: handler,
2234
+ });
2235
+ // Also forward error requests to the proxy so it can handle them.
2236
+ middlewares.push({
2237
+ name: "http-proxy-middleware-error-handler",
2238
+ middleware:
2239
+ /**
2240
+ * @param {Error} error
2241
+ * @param {Request} req
2242
+ * @param {Response} res
2243
+ * @param {NextFunction} next
2244
+ * @returns {any}
2245
+ */
2246
+ (error, req, res, next) => handler(req, res, next),
2247
+ });
2248
+ });
2256
2249
 
2257
2250
  middlewares.push({
2258
2251
  name: "webpack-dev-middleware",
@@ -2601,14 +2594,18 @@ class Server {
2601
2594
  * @returns {void}
2602
2595
  */
2603
2596
  runBonjour() {
2597
+ const { Bonjour } = require("bonjour-service");
2604
2598
  /**
2605
2599
  * @private
2606
- * @type {import("bonjour").Bonjour | undefined}
2600
+ * @type {Bonjour | undefined}
2607
2601
  */
2608
- this.bonjour = require("bonjour")();
2602
+ this.bonjour = new Bonjour();
2609
2603
  this.bonjour.publish({
2604
+ // @ts-expect-error
2610
2605
  name: `Webpack Dev Server ${os.hostname()}:${this.options.port}`,
2606
+ // @ts-expect-error
2611
2607
  port: /** @type {number} */ (this.options.port),
2608
+ // @ts-expect-error
2612
2609
  type:
2613
2610
  /** @type {ServerConfiguration} */
2614
2611
  (this.options.server).type === "http" ? "http" : "https",