@rspack/dev-server 1.0.10 → 1.1.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/index.js CHANGED
@@ -1,79 +1,39 @@
1
1
  // @ts-nocheck
2
- function ownKeys(object, enumerableOnly) {
3
- var keys = Object.keys(object);
4
- if (Object.getOwnPropertySymbols) {
5
- var symbols = Object.getOwnPropertySymbols(object);
6
- enumerableOnly &&
7
- (symbols = symbols.filter(function (sym) {
8
- return Object.getOwnPropertyDescriptor(object, sym).enumerable;
9
- })),
10
- keys.push.apply(keys, symbols);
11
- }
12
- return keys;
13
- }
14
- function _objectSpread(target) {
15
- for (var i = 1; i < arguments.length; i++) {
16
- var source = null != arguments[i] ? arguments[i] : {};
17
- i % 2
18
- ? ownKeys(Object(source), !0).forEach(function (key) {
19
- _defineProperty(target, key, source[key]);
20
- })
21
- : Object.getOwnPropertyDescriptors
22
- ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source))
23
- : ownKeys(Object(source)).forEach(function (key) {
24
- Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
25
- });
26
- }
27
- return target;
28
- }
29
- function _defineProperty(obj, key, value) {
30
- key = _toPropertyKey(key);
31
- if (key in obj) {
32
- Object.defineProperty(obj, key, {
33
- value: value,
34
- enumerable: true,
35
- configurable: true,
36
- writable: true
37
- });
38
- }
39
- else {
40
- obj[key] = value;
41
- }
42
- return obj;
43
- }
44
- function _toPropertyKey(arg) {
45
- var key = _toPrimitive(arg, "string");
46
- return typeof key === "symbol" ? key : String(key);
47
- }
48
- function _toPrimitive(input, hint) {
49
- if (typeof input !== "object" || input === null)
50
- return input;
51
- var prim = input[Symbol.toPrimitive];
52
- if (prim !== undefined) {
53
- var res = prim.call(input, hint || "default");
54
- if (typeof res !== "object")
55
- return res;
56
- throw new TypeError("@@toPrimitive must return a primitive value.");
57
- }
58
- return (hint === "string" ? String : Number)(input);
59
- }
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ import hotEmitter from "@rspack/core/hot/emitter.js";
60
14
  /* global __resourceQuery, __webpack_hash__ */
15
+ /* Rspack dev server runtime client */
61
16
  /// <reference types="webpack/module" />
62
17
  import webpackHotLog from "@rspack/core/hot/log.js";
63
- import stripAnsi from "webpack-dev-server/client/utils/stripAnsi.js";
64
- import parseURL from "webpack-dev-server/client/utils/parseURL.js";
18
+ import { createOverlay, formatProblem, } from "webpack-dev-server/client/overlay.js";
19
+ import socket from "webpack-dev-server/client/socket.js";
20
+ import { defineProgressElement, isProgressSupported, } from "webpack-dev-server/client/progress.js";
65
21
  import socket from "webpack-dev-server/client/socket.js";
66
- import { formatProblem, createOverlay } from "webpack-dev-server/client/overlay.js";
67
- import { log, logEnabledFeatures, setLogLevel } from "webpack-dev-server/client/utils/log.js";
22
+ import { log, setLogLevel } from "webpack-dev-server/client/utils/log.js";
68
23
  import sendMessage from "webpack-dev-server/client/utils/sendMessage.js";
69
- import reloadApp from "./utils/reloadApp.js";
70
- import createSocketURL from "webpack-dev-server/client/utils/createSocketURL.js";
24
+ /**
25
+ * @typedef {Object} OverlayOptions
26
+ * @property {boolean | (error: Error) => boolean} [warnings]
27
+ * @property {boolean | (error: Error) => boolean} [errors]
28
+ * @property {boolean | (error: Error) => boolean} [runtimeErrors]
29
+ * @property {string} [trustedTypesPolicyName]
30
+ */
71
31
  /**
72
32
  * @typedef {Object} Options
73
33
  * @property {boolean} hot
74
34
  * @property {boolean} liveReload
75
35
  * @property {boolean} progress
76
- * @property {boolean | { warnings?: boolean, errors?: boolean, runtimeErrors?: boolean, trustedTypesPolicyName?: string }} overlay
36
+ * @property {boolean | OverlayOptions} overlay
77
37
  * @property {string} [logging]
78
38
  * @property {number} [reconnect]
79
39
  */
@@ -84,39 +44,94 @@ import createSocketURL from "webpack-dev-server/client/utils/createSocketURL.js"
84
44
  * @property {string} [previousHash]
85
45
  */
86
46
  /**
87
- * @type {Status}
47
+ * @param {boolean | { warnings?: boolean | string; errors?: boolean | string; runtimeErrors?: boolean | string; }} overlayOptions
88
48
  */
89
- var status = {
90
- isUnloading: false,
91
- // TODO Workaround for webpack v4, `__webpack_hash__` is not replaced without HotModuleReplacement
92
- // eslint-disable-next-line camelcase
93
- currentHash: typeof __webpack_hash__ !== "undefined" ? __webpack_hash__ : ""
94
- };
95
- var decodeOverlayOptions = function decodeOverlayOptions(overlayOptions) {
49
+ var decodeOverlayOptions = function (overlayOptions) {
96
50
  if (typeof overlayOptions === "object") {
97
51
  ["warnings", "errors", "runtimeErrors"].forEach(function (property) {
98
52
  if (typeof overlayOptions[property] === "string") {
99
53
  var overlayFilterFunctionString = decodeURIComponent(overlayOptions[property]);
100
54
  // eslint-disable-next-line no-new-func
101
- var overlayFilterFunction = new Function("message", "var callback = ".concat(overlayFilterFunctionString, "\n return callback(message)"));
102
- overlayOptions[property] = overlayFilterFunction;
55
+ overlayOptions[property] = new Function("message", "var callback = ".concat(overlayFilterFunctionString, "\n\t\t\t\treturn callback(message)"));
103
56
  }
104
57
  });
105
58
  }
106
59
  };
107
- /** @type {Options} */
108
- var options = {
109
- hot: false,
110
- liveReload: false,
111
- progress: false,
112
- overlay: false
60
+ /**
61
+ * @param {string} resourceQuery
62
+ * @returns {{ [key: string]: string | boolean }}
63
+ */
64
+ var parseURL = function (resourceQuery) {
65
+ /** @type {{ [key: string]: string }} */
66
+ var result = {};
67
+ if (typeof resourceQuery === "string" && resourceQuery !== "") {
68
+ var searchParams = resourceQuery.slice(1).split("&");
69
+ for (var i = 0; i < searchParams.length; i++) {
70
+ var pair = searchParams[i].split("=");
71
+ result[pair[0]] = decodeURIComponent(pair[1]);
72
+ }
73
+ }
74
+ else {
75
+ // Else, get the url from the <script> this file was called with.
76
+ var scriptSource = getCurrentScriptSource();
77
+ var scriptSourceURL = void 0;
78
+ try {
79
+ // The placeholder `baseURL` with `window.location.href`,
80
+ // is to allow parsing of path-relative or protocol-relative URLs,
81
+ // and will have no effect if `scriptSource` is a fully valid URL.
82
+ scriptSourceURL = new URL(scriptSource, self.location.href);
83
+ }
84
+ catch (error) {
85
+ // URL parsing failed, do nothing.
86
+ // We will still proceed to see if we can recover using `resourceQuery`
87
+ }
88
+ if (scriptSourceURL) {
89
+ result = scriptSourceURL;
90
+ result.fromCurrentScript = true;
91
+ }
92
+ }
93
+ return result;
94
+ };
95
+ /**
96
+ * @type {Status}
97
+ */
98
+ var status = {
99
+ isUnloading: false,
100
+ // eslint-disable-next-line camelcase
101
+ currentHash: __webpack_hash__,
102
+ };
103
+ /**
104
+ * @returns {string}
105
+ */
106
+ var getCurrentScriptSource = function () {
107
+ // `document.currentScript` is the most accurate way to find the current script,
108
+ // but is not supported in all browsers.
109
+ if (document.currentScript) {
110
+ return document.currentScript.getAttribute("src");
111
+ }
112
+ // Fallback to getting all scripts running in the document.
113
+ var scriptElements = document.scripts || [];
114
+ var scriptElementsWithSrc = Array.prototype.filter.call(scriptElements, function (element) { return element.getAttribute("src"); });
115
+ if (scriptElementsWithSrc.length > 0) {
116
+ var currentScript = scriptElementsWithSrc[scriptElementsWithSrc.length - 1];
117
+ return currentScript.getAttribute("src");
118
+ }
119
+ // Fail as there was no script to use.
120
+ throw new Error("[webpack-dev-server] Failed to get current script source.");
113
121
  };
114
122
  var parsedResourceQuery = parseURL(__resourceQuery);
115
123
  var enabledFeatures = {
116
124
  "Hot Module Replacement": false,
117
125
  "Live Reloading": false,
118
126
  Progress: false,
119
- Overlay: false
127
+ Overlay: false,
128
+ };
129
+ /** @type {Options} */
130
+ var options = {
131
+ hot: false,
132
+ liveReload: false,
133
+ progress: false,
134
+ overlay: false,
120
135
  };
121
136
  if (parsedResourceQuery.hot === "true") {
122
137
  options.hot = true;
@@ -139,11 +154,7 @@ if (parsedResourceQuery.overlay) {
139
154
  }
140
155
  // Fill in default "true" params for partially-specified objects.
141
156
  if (typeof options.overlay === "object") {
142
- options.overlay = _objectSpread({
143
- errors: true,
144
- warnings: true,
145
- runtimeErrors: true
146
- }, options.overlay);
157
+ options.overlay = __assign({ errors: true, warnings: true, runtimeErrors: true }, options.overlay);
147
158
  decodeOverlayOptions(options.overlay);
148
159
  }
149
160
  enabledFeatures.Overlay = true;
@@ -157,14 +168,29 @@ if (typeof parsedResourceQuery.reconnect !== "undefined") {
157
168
  /**
158
169
  * @param {string} level
159
170
  */
160
- function setAllLogLevel(level) {
171
+ var setAllLogLevel = function (level) {
161
172
  // This is needed because the HMR logger operate separately from dev server logger
162
173
  webpackHotLog.setLogLevel(level === "verbose" || level === "log" ? "info" : level);
163
174
  setLogLevel(level);
164
- }
175
+ };
165
176
  if (options.logging) {
166
177
  setAllLogLevel(options.logging);
167
178
  }
179
+ var logEnabledFeatures = function (features) {
180
+ var listEnabledFeatures = Object.keys(features);
181
+ if (!features || listEnabledFeatures.length === 0) {
182
+ return;
183
+ }
184
+ var logString = "Server started:";
185
+ // Server started: Hot Module Replacement enabled, Live Reloading enabled, Overlay disabled.
186
+ for (var i = 0; i < listEnabledFeatures.length; i++) {
187
+ var key = listEnabledFeatures[i];
188
+ logString += " ".concat(key, " ").concat(features[key] ? "enabled" : "disabled", ",");
189
+ }
190
+ // replace last comma with a period
191
+ logString = logString.slice(0, -1).concat(".");
192
+ log.info(logString);
193
+ };
168
194
  logEnabledFeatures(enabledFeatures);
169
195
  self.addEventListener("beforeunload", function () {
170
196
  status.isUnloading = true;
@@ -173,41 +199,108 @@ var overlay = typeof window !== "undefined"
173
199
  ? createOverlay(typeof options.overlay === "object"
174
200
  ? {
175
201
  trustedTypesPolicyName: options.overlay.trustedTypesPolicyName,
176
- catchRuntimeError: options.overlay.runtimeErrors
202
+ catchRuntimeError: options.overlay.runtimeErrors,
177
203
  }
178
204
  : {
179
205
  trustedTypesPolicyName: false,
180
- catchRuntimeError: options.overlay
206
+ catchRuntimeError: options.overlay,
181
207
  })
182
- : {
183
- send: function send() { }
184
- };
185
- /* Rspack dev server runtime client */
208
+ : { send: function () { } };
209
+ /**
210
+ * @param {Options} options
211
+ * @param {Status} currentStatus
212
+ */
213
+ var reloadApp = function (_a, currentStatus) {
214
+ var hot = _a.hot, liveReload = _a.liveReload;
215
+ if (currentStatus.isUnloading) {
216
+ return;
217
+ }
218
+ var currentHash = currentStatus.currentHash, previousHash = currentStatus.previousHash;
219
+ var isInitial = currentHash.indexOf(/** @type {string} */ (previousHash)) >= 0;
220
+ if (isInitial) {
221
+ return;
222
+ }
223
+ /**
224
+ * @param {Window} rootWindow
225
+ * @param {number} intervalId
226
+ */
227
+ function applyReload(rootWindow, intervalId) {
228
+ clearInterval(intervalId);
229
+ log.info("App updated. Reloading...");
230
+ rootWindow.location.reload();
231
+ }
232
+ var search = self.location.search.toLowerCase();
233
+ var allowToHot = search.indexOf("webpack-dev-server-hot=false") === -1;
234
+ var allowToLiveReload = search.indexOf("webpack-dev-server-live-reload=false") === -1;
235
+ if (hot && allowToHot) {
236
+ log.info("App hot update...");
237
+ hotEmitter.emit("webpackHotUpdate", currentStatus.currentHash);
238
+ if (typeof self !== "undefined" && self.window) {
239
+ // broadcast update to window
240
+ self.postMessage("webpackHotUpdate".concat(currentStatus.currentHash), "*");
241
+ }
242
+ }
243
+ // allow refreshing the page only if liveReload isn't disabled
244
+ else if (liveReload && allowToLiveReload) {
245
+ var rootWindow_1 = self;
246
+ // use parent window for reload (in case we're in an iframe with no valid src)
247
+ var intervalId_1 = self.setInterval(function () {
248
+ if (rootWindow_1.location.protocol !== "about:") {
249
+ // reload immediately if protocol is valid
250
+ applyReload(rootWindow_1, intervalId_1);
251
+ }
252
+ else {
253
+ rootWindow_1 = rootWindow_1.parent;
254
+ if (rootWindow_1.parent === rootWindow_1) {
255
+ // if parent equals current window we've reached the root which would continue forever, so trigger a reload anyways
256
+ applyReload(rootWindow_1, intervalId_1);
257
+ }
258
+ }
259
+ });
260
+ }
261
+ };
262
+ var ansiRegex = new RegExp([
263
+ "[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)",
264
+ "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))",
265
+ ].join("|"), "g");
266
+ /**
267
+ *
268
+ * Strip [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) from a string.
269
+ * Adapted from code originally released by Sindre Sorhus
270
+ * Licensed the MIT License
271
+ *
272
+ * @param {string} string
273
+ * @return {string}
274
+ */
275
+ var stripAnsi = function (string) {
276
+ if (typeof string !== "string") {
277
+ throw new TypeError("Expected a `string`, got `".concat(typeof string, "`"));
278
+ }
279
+ return string.replace(ansiRegex, "");
280
+ };
186
281
  var onSocketMessage = {
187
- hot: function hot() {
282
+ hot: function () {
188
283
  if (parsedResourceQuery.hot === "false") {
189
284
  return;
190
285
  }
191
286
  options.hot = true;
192
287
  },
193
- liveReload: function liveReload() {
288
+ liveReload: function () {
194
289
  if (parsedResourceQuery["live-reload"] === "false") {
195
290
  return;
196
291
  }
197
292
  options.liveReload = true;
198
293
  },
199
- invalid: function invalid() {
294
+ invalid: function () {
200
295
  log.info("App updated. Recompiling...");
201
296
  // Fixes #1042. overlay doesn't clear if errors are fixed but warnings remain.
202
297
  if (options.overlay) {
203
- overlay.send({
204
- type: "DISMISS"
205
- });
298
+ overlay.send({ type: "DISMISS" });
206
299
  }
207
300
  sendMessage("Invalid");
208
301
  },
209
302
  /**
210
- * @param {string | undefined} _hash
303
+ * @param {string | undefined} hash
211
304
  */
212
305
  hash: function hash(_hash) {
213
306
  if (!_hash) {
@@ -220,7 +313,7 @@ var onSocketMessage = {
220
313
  /**
221
314
  * @param {boolean} value
222
315
  */
223
- overlay: function overlay(value) {
316
+ overlay: function (value) {
224
317
  if (typeof document === "undefined") {
225
318
  return;
226
319
  }
@@ -230,7 +323,7 @@ var onSocketMessage = {
230
323
  /**
231
324
  * @param {number} value
232
325
  */
233
- reconnect: function reconnect(value) {
326
+ reconnect: function (value) {
234
327
  if (parsedResourceQuery.reconnect === "false") {
235
328
  return;
236
329
  }
@@ -239,7 +332,7 @@ var onSocketMessage = {
239
332
  /**
240
333
  * @param {boolean} value
241
334
  */
242
- progress: function progress(value) {
335
+ progress: function (value) {
243
336
  options.progress = value;
244
337
  },
245
338
  /**
@@ -247,54 +340,51 @@ var onSocketMessage = {
247
340
  */
248
341
  "progress-update": function progressUpdate(data) {
249
342
  if (options.progress) {
250
- log.info(""
251
- .concat(data.pluginName ? "[".concat(data.pluginName, "] ") : "")
252
- .concat(data.percent, "% - ")
253
- .concat(data.msg, "."));
343
+ log.info("".concat(data.pluginName ? "[".concat(data.pluginName, "] ") : "").concat(data.percent, "% - ").concat(data.msg, "."));
344
+ }
345
+ if (isProgressSupported()) {
346
+ if (typeof options.progress === "string") {
347
+ var progress = document.querySelector("wds-progress");
348
+ if (!progress) {
349
+ defineProgressElement();
350
+ progress = document.createElement("wds-progress");
351
+ document.body.appendChild(progress);
352
+ }
353
+ progress.setAttribute("progress", data.percent);
354
+ progress.setAttribute("type", options.progress);
355
+ }
254
356
  }
255
357
  sendMessage("Progress", data);
256
358
  },
257
359
  "still-ok": function stillOk() {
258
360
  log.info("Nothing changed.");
259
361
  if (options.overlay) {
260
- overlay.send({
261
- type: "DISMISS"
262
- });
362
+ overlay.send({ type: "DISMISS" });
263
363
  }
264
364
  sendMessage("StillOk");
265
365
  },
266
- ok: function ok() {
366
+ ok: function () {
267
367
  sendMessage("Ok");
268
368
  if (options.overlay) {
269
- overlay.send({
270
- type: "DISMISS"
271
- });
369
+ overlay.send({ type: "DISMISS" });
272
370
  }
273
371
  reloadApp(options, status);
274
372
  },
275
- // TODO: remove in v5 in favor of 'static-changed'
276
- /**
277
- * @param {string} file
278
- */
279
- "content-changed": function contentChanged(file) {
280
- log.info("".concat(file ? '"'.concat(file, '"') : "Content", " from static directory was changed. Reloading..."));
281
- self.location.reload();
282
- },
283
373
  /**
284
374
  * @param {string} file
285
375
  */
286
376
  "static-changed": function staticChanged(file) {
287
- log.info("".concat(file ? '"'.concat(file, '"') : "Content", " from static directory was changed. Reloading..."));
377
+ log.info("".concat(file ? "\"".concat(file, "\"") : "Content", " from static directory was changed. Reloading..."));
288
378
  self.location.reload();
289
379
  },
290
380
  /**
291
381
  * @param {Error[]} warnings
292
382
  * @param {any} params
293
383
  */
294
- warnings: function warnings(_warnings, params) {
384
+ warnings: function (warnings, params) {
295
385
  log.warn("Warnings while compiling.");
296
- var printableWarnings = _warnings.map(function (error) {
297
- var _formatProblem = formatProblem("warning", error), header = _formatProblem.header, body = _formatProblem.body;
386
+ var printableWarnings = warnings.map(function (error) {
387
+ var _a = formatProblem("warning", error), header = _a.header, body = _a.body;
298
388
  return "".concat(header, "\n").concat(stripAnsi(body));
299
389
  });
300
390
  sendMessage("Warnings", printableWarnings);
@@ -306,13 +396,13 @@ var onSocketMessage = {
306
396
  : options.overlay && options.overlay.warnings;
307
397
  if (overlayWarningsSetting) {
308
398
  var warningsToDisplay = typeof overlayWarningsSetting === "function"
309
- ? _warnings.filter(overlayWarningsSetting)
310
- : _warnings;
399
+ ? warnings.filter(overlayWarningsSetting)
400
+ : warnings;
311
401
  if (warningsToDisplay.length) {
312
402
  overlay.send({
313
403
  type: "BUILD_ERROR",
314
404
  level: "warning",
315
- messages: _warnings
405
+ messages: warnings,
316
406
  });
317
407
  }
318
408
  }
@@ -324,10 +414,10 @@ var onSocketMessage = {
324
414
  /**
325
415
  * @param {Error[]} errors
326
416
  */
327
- errors: function errors(_errors) {
417
+ errors: function (errors) {
328
418
  log.error("Errors while compiling. Reload prevented.");
329
- var printableErrors = _errors.map(function (error) {
330
- var _formatProblem2 = formatProblem("error", error), header = _formatProblem2.header, body = _formatProblem2.body;
419
+ var printableErrors = errors.map(function (error) {
420
+ var _a = formatProblem("error", error), header = _a.header, body = _a.body;
331
421
  return "".concat(header, "\n").concat(stripAnsi(body));
332
422
  });
333
423
  sendMessage("Errors", printableErrors);
@@ -339,13 +429,13 @@ var onSocketMessage = {
339
429
  : options.overlay && options.overlay.errors;
340
430
  if (overlayErrorsSettings) {
341
431
  var errorsToDisplay = typeof overlayErrorsSettings === "function"
342
- ? _errors.filter(overlayErrorsSettings)
343
- : _errors;
432
+ ? errors.filter(overlayErrorsSettings)
433
+ : errors;
344
434
  if (errorsToDisplay.length) {
345
435
  overlay.send({
346
436
  type: "BUILD_ERROR",
347
437
  level: "error",
348
- messages: _errors
438
+ messages: errors,
349
439
  });
350
440
  }
351
441
  }
@@ -353,18 +443,137 @@ var onSocketMessage = {
353
443
  /**
354
444
  * @param {Error} error
355
445
  */
356
- error: function error(_error) {
357
- log.error(_error);
446
+ error: function (error) {
447
+ log.error(error);
358
448
  },
359
- close: function close() {
449
+ close: function () {
360
450
  log.info("Disconnected!");
361
451
  if (options.overlay) {
362
- overlay.send({
363
- type: "DISMISS"
364
- });
452
+ overlay.send({ type: "DISMISS" });
365
453
  }
366
454
  sendMessage("Close");
455
+ },
456
+ };
457
+ /**
458
+ * @param {{ protocol?: string, auth?: string, hostname?: string, port?: string, pathname?: string, search?: string, hash?: string, slashes?: boolean }} objURL
459
+ * @returns {string}
460
+ */
461
+ var formatURL = function (objURL) {
462
+ var protocol = objURL.protocol || "";
463
+ if (protocol && protocol.substr(-1) !== ":") {
464
+ protocol += ":";
465
+ }
466
+ var auth = objURL.auth || "";
467
+ if (auth) {
468
+ auth = encodeURIComponent(auth);
469
+ auth = auth.replace(/%3A/i, ":");
470
+ auth += "@";
471
+ }
472
+ var host = "";
473
+ if (objURL.hostname) {
474
+ host =
475
+ auth +
476
+ (objURL.hostname.indexOf(":") === -1
477
+ ? objURL.hostname
478
+ : "[".concat(objURL.hostname, "]"));
479
+ if (objURL.port) {
480
+ host += ":".concat(objURL.port);
481
+ }
482
+ }
483
+ var pathname = objURL.pathname || "";
484
+ if (objURL.slashes) {
485
+ host = "//".concat(host || "");
486
+ if (pathname && pathname.charAt(0) !== "/") {
487
+ pathname = "/".concat(pathname);
488
+ }
489
+ }
490
+ else if (!host) {
491
+ host = "";
492
+ }
493
+ var search = objURL.search || "";
494
+ if (search && search.charAt(0) !== "?") {
495
+ search = "?".concat(search);
496
+ }
497
+ var hash = objURL.hash || "";
498
+ if (hash && hash.charAt(0) !== "#") {
499
+ hash = "#".concat(hash);
500
+ }
501
+ pathname = pathname.replace(/[?#]/g,
502
+ /**
503
+ * @param {string} match
504
+ * @returns {string}
505
+ */
506
+ function (match) { return encodeURIComponent(match); });
507
+ search = search.replace("#", "%23");
508
+ return "".concat(protocol).concat(host).concat(pathname).concat(search).concat(hash);
509
+ };
510
+ /**
511
+ * @param {URL & { fromCurrentScript?: boolean }} parsedURL
512
+ * @returns {string}
513
+ */
514
+ var createSocketURL = function (parsedURL) {
515
+ var hostname = parsedURL.hostname;
516
+ // Node.js module parses it as `::`
517
+ // `new URL(urlString, [baseURLString])` parses it as '[::]'
518
+ var isInAddrAny = hostname === "0.0.0.0" || hostname === "::" || hostname === "[::]";
519
+ // why do we need this check?
520
+ // hostname n/a for file protocol (example, when using electron, ionic)
521
+ // see: https://github.com/webpack/webpack-dev-server/pull/384
522
+ if (isInAddrAny &&
523
+ self.location.hostname &&
524
+ self.location.protocol.indexOf("http") === 0) {
525
+ hostname = self.location.hostname;
526
+ }
527
+ var socketURLProtocol = parsedURL.protocol || self.location.protocol;
528
+ // When https is used in the app, secure web sockets are always necessary because the browser doesn't accept non-secure web sockets.
529
+ if (socketURLProtocol === "auto:" ||
530
+ (hostname && isInAddrAny && self.location.protocol === "https:")) {
531
+ socketURLProtocol = self.location.protocol;
532
+ }
533
+ socketURLProtocol = socketURLProtocol.replace(/^(?:http|.+-extension|file)/i, "ws");
534
+ var socketURLAuth = "";
535
+ // `new URL(urlString, [baseURLstring])` doesn't have `auth` property
536
+ // Parse authentication credentials in case we need them
537
+ if (parsedURL.username) {
538
+ socketURLAuth = parsedURL.username;
539
+ // Since HTTP basic authentication does not allow empty username,
540
+ // we only include password if the username is not empty.
541
+ if (parsedURL.password) {
542
+ // Result: <username>:<password>
543
+ socketURLAuth = socketURLAuth.concat(":", parsedURL.password);
544
+ }
545
+ }
546
+ // In case the host is a raw IPv6 address, it can be enclosed in
547
+ // the brackets as the brackets are needed in the final URL string.
548
+ // Need to remove those as url.format blindly adds its own set of brackets
549
+ // if the host string contains colons. That would lead to non-working
550
+ // double brackets (e.g. [[::]]) host
551
+ //
552
+ // All of these web socket url params are optionally passed in through resourceQuery,
553
+ // so we need to fall back to the default if they are not provided
554
+ var socketURLHostname = (hostname ||
555
+ self.location.hostname ||
556
+ "localhost").replace(/^\[(.*)\]$/, "$1");
557
+ var socketURLPort = parsedURL.port;
558
+ if (!socketURLPort || socketURLPort === "0") {
559
+ socketURLPort = self.location.port;
560
+ }
561
+ // If path is provided it'll be passed in via the resourceQuery as a
562
+ // query param so it has to be parsed out of the querystring in order for the
563
+ // client to open the socket to the correct location.
564
+ var socketURLPathname = "/ws";
565
+ if (parsedURL.pathname && !parsedURL.fromCurrentScript) {
566
+ socketURLPathname = parsedURL.pathname;
367
567
  }
568
+ return formatURL({
569
+ protocol: socketURLProtocol,
570
+ auth: socketURLAuth,
571
+ hostname: socketURLHostname,
572
+ port: socketURLPort,
573
+ pathname: socketURLPathname,
574
+ slashes: true,
575
+ });
368
576
  };
369
577
  var socketURL = createSocketURL(parsedResourceQuery);
370
578
  socket(socketURL, onSocketMessage, options.reconnect);
579
+ export { getCurrentScriptSource, parseURL, createSocketURL };
@@ -10,7 +10,7 @@ var _defColors = {
10
10
  magenta: "ff00ff",
11
11
  cyan: "00ffee",
12
12
  lightgrey: "f0f0f0",
13
- darkgrey: "888"
13
+ darkgrey: "888",
14
14
  };
15
15
  var _styles = {
16
16
  30: "black",
@@ -20,10 +20,10 @@ var _styles = {
20
20
  34: "blue",
21
21
  35: "magenta",
22
22
  36: "cyan",
23
- 37: "lightgrey"
23
+ 37: "lightgrey",
24
24
  };
25
25
  var _colorMode = {
26
- 2: "rgb"
26
+ 2: "rgb",
27
27
  };
28
28
  var _openTags = {
29
29
  1: "font-weight:bold",
@@ -53,12 +53,12 @@ var _openTags = {
53
53
  match.advance(4);
54
54
  return "background-color: rgb(".concat(r, ",").concat(g, ",").concat(b, ")");
55
55
  }
56
- }
56
+ },
57
57
  };
58
58
  var _openTagToCloseTag = {
59
59
  3: "23",
60
60
  4: "24",
61
- 9: "29"
61
+ 9: "29",
62
62
  };
63
63
  var _closeTags = {
64
64
  0: function (ansiCodes) {
@@ -80,7 +80,7 @@ var _closeTags = {
80
80
  },
81
81
  23: "</i>",
82
82
  24: "</u>",
83
- 29: "</del>" // reset delete
83
+ 29: "</del>", // reset delete
84
84
  };
85
85
  for (var _i = 0, _a = [21, 22, 27, 28, 39, 49]; _i < _a.length; _i++) {
86
86
  var n = _a[_i];
@@ -115,7 +115,7 @@ export default function ansiHTML(text) {
115
115
  Object.defineProperty(match, "advance", {
116
116
  value: function (count) {
117
117
  this.splice(0, count);
118
- }
118
+ },
119
119
  });
120
120
  var rep = "";
121
121
  var seq;
@@ -127,7 +127,8 @@ export default function ansiHTML(text) {
127
127
  function applySeq(seq) {
128
128
  var other = _openTags[seq];
129
129
  if (other &&
130
- (other = typeof other === "function" ? other(match) : other)) {
130
+ (other =
131
+ typeof other === "function" ? other(match) : other)) {
131
132
  // If reset signal is encountered, we have to reset everything.
132
133
  var ret_1 = "";
133
134
  if (seq === "0") {
@@ -213,10 +214,10 @@ ansiHTML.reset = function () {
213
214
  ansiHTML.tags = {};
214
215
  if (Object.defineProperty) {
215
216
  Object.defineProperty(ansiHTML.tags, "open", {
216
- get: function () { return _openTags; }
217
+ get: function () { return _openTags; },
217
218
  });
218
219
  Object.defineProperty(ansiHTML.tags, "close", {
219
- get: function () { return _closeTags; }
220
+ get: function () { return _closeTags; },
220
221
  });
221
222
  }
222
223
  else {
@@ -8,6 +8,7 @@ const node_crypto_1 = __importDefault(require("node:crypto"));
8
8
  const node_path_1 = require("node:path");
9
9
  const node_url_1 = require("node:url");
10
10
  const mime_types_1 = __importDefault(require("mime-types"));
11
+ // biome-ignore lint/suspicious/noExplicitAny: _
11
12
  function etag(buf) {
12
13
  const hash = node_crypto_1.default.createHash("sha256").update(buf).digest("hex");
13
14
  const etag = hash;
package/dist/server.d.ts CHANGED
@@ -30,5 +30,6 @@ export declare class RspackDevServer extends WebpackDevServer {
30
30
  static version: string;
31
31
  constructor(options: DevServer, compiler: Compiler | MultiCompiler);
32
32
  initialize(): Promise<void>;
33
- private addAdditionalEntries;
33
+ getClientEntry(): string;
34
+ getClientHotEntry(): string | undefined;
34
35
  }
package/dist/server.js CHANGED
@@ -8,14 +8,13 @@ const core_1 = require("@rspack/core");
8
8
  const webpack_dev_server_1 = __importDefault(require("webpack-dev-server"));
9
9
  // @ts-ignore 'package.json' is not under 'rootDir'
10
10
  const package_json_1 = require("../package.json");
11
- const alias_1 = require("./alias");
12
11
  const patch_1 = require("./patch");
13
12
  (0, patch_1.applyDevServerPatch)();
14
13
  const getFreePort = async function getFreePort(port, host) {
15
14
  if (typeof port !== "undefined" && port !== null && port !== "auto") {
16
15
  return port;
17
16
  }
18
- const pRetry = require("p-retry");
17
+ const { default: pRetry } = await import("p-retry");
19
18
  const getPort = require("webpack-dev-server/lib/getPort");
20
19
  const basePort = typeof process.env.WEBPACK_DEV_SERVER_BASE_PORT !== "undefined"
21
20
  ? Number.parseInt(process.env.WEBPACK_DEV_SERVER_BASE_PORT, 10)
@@ -26,12 +25,13 @@ const getFreePort = async function getFreePort(port, host) {
26
25
  ? Number.parseInt(process.env.WEBPACK_DEV_SERVER_PORT_RETRY, 10)
27
26
  : 3;
28
27
  return pRetry(() => getPort(basePort, host), {
29
- retries: defaultPortRetry
28
+ retries: defaultPortRetry,
30
29
  });
31
30
  };
32
31
  webpack_dev_server_1.default.getFreePort = getFreePort;
33
32
  class RspackDevServer extends webpack_dev_server_1.default {
34
33
  constructor(options, compiler) {
34
+ // biome-ignore lint/suspicious/noExplicitAny: _
35
35
  super(options, compiler);
36
36
  // override
37
37
  }
@@ -48,26 +48,22 @@ class RspackDevServer extends webpack_dev_server_1.default {
48
48
  }
49
49
  compiler.options.resolve.alias = {
50
50
  "ansi-html-community": require.resolve("@rspack/dev-server/client/utils/ansiHTML"),
51
- ...compiler.options.resolve.alias
51
+ ...compiler.options.resolve.alias,
52
52
  };
53
53
  }
54
54
  }
55
55
  // @ts-expect-error
56
56
  await super.initialize();
57
57
  }
58
- // @ts-ignore
59
- addAdditionalEntries(compiler) {
60
- (0, alias_1.addResolveAlias)("webpack-dev-server", {
61
- "../client/index.js": require.resolve("@rspack/dev-server/client/index"),
62
- "webpack/hot/only-dev-server": require.resolve("@rspack/core/hot/only-dev-server"),
63
- "webpack/hot/dev-server": require.resolve("@rspack/core/hot/dev-server")
64
- });
65
- try {
66
- // @ts-expect-error
67
- super.addAdditionalEntries(compiler);
58
+ getClientEntry() {
59
+ return require.resolve("@rspack/dev-server/client/index");
60
+ }
61
+ getClientHotEntry() {
62
+ if (this.options.hot === "only") {
63
+ return require.resolve("@rspack/core/hot/only-dev-server");
68
64
  }
69
- finally {
70
- (0, alias_1.removeResolveAlias)("webpack-dev-server");
65
+ if (this.options.hot) {
66
+ return require.resolve("@rspack/core/hot/dev-server");
71
67
  }
72
68
  }
73
69
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rspack/dev-server",
3
- "version": "1.0.10",
3
+ "version": "1.1.0",
4
4
  "license": "MIT",
5
5
  "description": "Development server for rspack",
6
6
  "main": "./dist/index.js",
@@ -41,53 +41,51 @@
41
41
  },
42
42
  "devDependencies": {
43
43
  "@biomejs/biome": "^1.8.3",
44
+ "@jest/reporters": "29.7.0",
44
45
  "@jest/test-sequencer": "^29.7.0",
45
46
  "@rspack/core": "1.0.11",
46
47
  "@rspack/plugin-react-refresh": "1.0.0",
47
- "@types/connect-history-api-fallback": "1.5.4",
48
48
  "@types/express": "4.17.21",
49
+ "@types/jest": "29.5.12",
49
50
  "@types/mime-types": "2.1.4",
50
51
  "@types/ws": "8.5.10",
52
+ "@hono/node-server": "^1.13.3",
53
+ "cross-env": "^7.0.3",
51
54
  "css-loader": "^6.11.0",
55
+ "connect": "^3.7.0",
56
+ "execa": "9.3.0",
57
+ "fs-extra": "11.2.0",
52
58
  "graceful-fs": "4.2.10",
53
59
  "http-proxy": "^1.18.1",
60
+ "hono": "^4.6.8",
61
+ "jest": "29.7.0",
62
+ "jest-cli": "29.7.0",
63
+ "jest-environment-node": "29.7.0",
54
64
  "jest-serializer-path": "^0.1.15",
65
+ "nano-staged": "^0.8.0",
55
66
  "prettier": "3.2.5",
56
67
  "puppeteer": "^23.2.2",
68
+ "react-refresh": "0.14.0",
57
69
  "require-from-string": "^2.0.2",
70
+ "semver": "7.6.3",
71
+ "simple-git-hooks": "^2.11.1",
58
72
  "sockjs-client": "^1.6.1",
59
73
  "style-loader": "^3.3.3",
60
74
  "supertest": "^6.1.3",
61
75
  "tcp-port-used": "^1.0.2",
76
+ "ts-jest": "29.1.2",
62
77
  "typescript": "5.0.2",
63
78
  "wait-for-expect": "^3.0.2",
64
- "@jest/reporters": "29.7.0",
65
- "@types/jest": "29.5.12",
66
- "cross-env": "^7.0.3",
67
- "husky": "^9.0.0",
68
- "jest": "29.7.0",
69
- "jest-cli": "29.7.0",
70
- "jest-environment-node": "29.7.0",
71
- "rimraf": "3.0.2",
72
- "ts-jest": "29.1.2",
73
- "webpack": "^5.94.0",
74
- "webpack-cli": "5.1.4",
75
- "react-refresh": "0.14.0",
76
- "execa": "9.3.0",
77
- "fs-extra": "11.2.0",
78
- "nano-staged": "^0.8.0",
79
- "semver": "7.6.3",
80
- "simple-git-hooks": "^2.11.1"
79
+ "webpack": "^5.94.0"
81
80
  },
82
81
  "dependencies": {
83
82
  "chokidar": "^3.6.0",
84
- "connect-history-api-fallback": "^2.0.0",
85
83
  "express": "^4.19.2",
86
84
  "http-proxy-middleware": "^2.0.6",
87
85
  "mime-types": "^2.1.35",
88
- "p-retry": "4.6.2",
86
+ "p-retry": "^6.2.0",
89
87
  "webpack-dev-middleware": "^7.4.2",
90
- "webpack-dev-server": "5.0.4",
88
+ "webpack-dev-server": "5.2.0",
91
89
  "ws": "^8.16.0"
92
90
  },
93
91
  "peerDependencies": {
@@ -1,60 +0,0 @@
1
- // @ts-nocheck
2
- import hotEmitter from "@rspack/core/hot/emitter.js";
3
- import { log } from "webpack-dev-server/client/utils/log.js";
4
- /** @typedef {import("../index").Options} Options
5
- /** @typedef {import("../index").Status} Status
6
-
7
- /**
8
- * @param {Options} options
9
- * @param {Status} status
10
- */
11
- function reloadApp(_ref, status) {
12
- var hot = _ref.hot, liveReload = _ref.liveReload;
13
- if (status.isUnloading) {
14
- return;
15
- }
16
- var currentHash = status.currentHash, previousHash = status.previousHash;
17
- var isInitial = currentHash.indexOf(/** @type {string} */ previousHash) >= 0;
18
- if (isInitial) {
19
- return;
20
- }
21
- /**
22
- * @param {Window} rootWindow
23
- * @param {number} intervalId
24
- */
25
- function applyReload(rootWindow, intervalId) {
26
- clearInterval(intervalId);
27
- log.info("App updated. Reloading...");
28
- rootWindow.location.reload();
29
- }
30
- var search = self.location.search.toLowerCase();
31
- var allowToHot = search.indexOf("webpack-dev-server-hot=false") === -1;
32
- var allowToLiveReload = search.indexOf("webpack-dev-server-live-reload=false") === -1;
33
- if (hot && allowToHot) {
34
- log.info("App hot update...");
35
- hotEmitter.emit("webpackHotUpdate", status.currentHash);
36
- if (typeof self !== "undefined" && self.window) {
37
- // broadcast update to window
38
- self.postMessage("webpackHotUpdate".concat(status.currentHash), "*");
39
- }
40
- }
41
- // allow refreshing the page only if liveReload isn't disabled
42
- else if (liveReload && allowToLiveReload) {
43
- var rootWindow = self;
44
- // use parent window for reload (in case we're in an iframe with no valid src)
45
- var intervalId = self.setInterval(function () {
46
- if (rootWindow.location.protocol !== "about:") {
47
- // reload immediately if protocol is valid
48
- applyReload(rootWindow, intervalId);
49
- }
50
- else {
51
- rootWindow = rootWindow.parent;
52
- if (rootWindow.parent === rootWindow) {
53
- // if parent equals current window we've reached the root which would continue forever, so trigger a reload anyways
54
- applyReload(rootWindow, intervalId);
55
- }
56
- }
57
- });
58
- }
59
- }
60
- export default reloadApp;
package/dist/alias.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export declare const addResolveAlias: (name: string, aliasMap: Record<string, string>) => void;
2
- export declare const removeResolveAlias: (name: string) => void;
package/dist/alias.js DELETED
@@ -1,45 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.removeResolveAlias = exports.addResolveAlias = void 0;
4
- const Module = require("node:module");
5
- const MODULE_MAP = {};
6
- const RESOLVER_MAP = {};
7
- const addResolveAlias = (name, aliasMap) => {
8
- const modulePath = require.resolve(name);
9
- if (modulePath in RESOLVER_MAP) {
10
- throw new Error(`Should not add resolve alias to ${name} again.`);
11
- }
12
- const m = require.cache[modulePath];
13
- if (!m) {
14
- throw new Error("Failed to resolve webpack-dev-server.");
15
- }
16
- RESOLVER_MAP[modulePath] = m.require.resolve;
17
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
18
- m.require.resolve = ((id, options) => aliasMap[id] ||
19
- RESOLVER_MAP[modulePath].apply(m.require, [
20
- id,
21
- options,
22
- ]));
23
- MODULE_MAP[modulePath] = Module._resolveFilename;
24
- Module._resolveFilename = (request, mod, ...args) => {
25
- if (mod.filename === modulePath && aliasMap[request]) {
26
- return aliasMap[request];
27
- }
28
- return MODULE_MAP[modulePath](request, mod, ...args);
29
- };
30
- };
31
- exports.addResolveAlias = addResolveAlias;
32
- const removeResolveAlias = (name) => {
33
- const modulePath = require.resolve(name);
34
- if (!(modulePath in RESOLVER_MAP)) {
35
- return;
36
- }
37
- const m = require.cache[modulePath];
38
- if (!m) {
39
- throw new Error("Failed to resolve webpack-dev-server");
40
- }
41
- Module._resolveFilename = MODULE_MAP[modulePath];
42
- m.require.resolve = RESOLVER_MAP[modulePath];
43
- delete RESOLVER_MAP[modulePath];
44
- };
45
- exports.removeResolveAlias = removeResolveAlias;