webpack-dev-server 4.4.0 → 4.7.1
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 +57 -65
- package/bin/cli-flags.js +268 -244
- package/bin/process-arguments.js +87 -7
- package/bin/webpack-dev-server.js +3 -0
- package/client/clients/SockJSClient.js +26 -3
- package/client/clients/WebSocketClient.js +16 -1
- package/client/index.js +76 -3
- package/client/modules/logger/index.js +3 -0
- package/client/modules/sockjs-client/index.js +18 -16
- package/client/overlay.js +38 -3
- package/client/socket.js +19 -8
- package/client/utils/createSocketURL.js +71 -4
- package/client/utils/getCurrentScriptSource.js +3 -0
- package/client/utils/log.js +6 -1
- package/client/utils/parseURL.js +17 -19
- package/client/utils/reloadApp.js +15 -2
- package/client/utils/sendMessage.js +5 -0
- package/lib/Server.js +1887 -824
- package/lib/options.json +42 -22
- package/lib/servers/BaseServer.js +8 -0
- package/lib/servers/SockJSServer.js +42 -9
- package/lib/servers/WebsocketServer.js +66 -35
- package/package.json +27 -17
- package/types/bin/cli-flags.d.ts +934 -0
- package/types/bin/process-arguments.d.ts +50 -0
- package/types/bin/webpack-dev-server.d.ts +27 -0
- package/types/lib/Server.d.ts +3388 -0
- package/types/lib/servers/BaseServer.d.ts +15 -0
- package/types/lib/servers/SockJSServer.d.ts +12 -0
- package/types/lib/servers/WebsocketServer.d.ts +13 -0
package/client/overlay.js
CHANGED
|
@@ -14,8 +14,14 @@ var colors = {
|
|
|
14
14
|
lightgrey: "EBE7E3",
|
|
15
15
|
darkgrey: "6D7891"
|
|
16
16
|
};
|
|
17
|
+
/** @type {HTMLIFrameElement | null | undefined} */
|
|
18
|
+
|
|
17
19
|
var iframeContainerElement;
|
|
20
|
+
/** @type {HTMLDivElement | null | undefined} */
|
|
21
|
+
|
|
18
22
|
var containerElement;
|
|
23
|
+
/** @type {Array<(element: HTMLDivElement) => void>} */
|
|
24
|
+
|
|
19
25
|
var onLoadQueue = [];
|
|
20
26
|
ansiHTML.setColors(colors);
|
|
21
27
|
|
|
@@ -34,7 +40,11 @@ function createContainer() {
|
|
|
34
40
|
iframeContainerElement.style.zIndex = 9999999999;
|
|
35
41
|
|
|
36
42
|
iframeContainerElement.onload = function () {
|
|
37
|
-
containerElement =
|
|
43
|
+
containerElement =
|
|
44
|
+
/** @type {Document} */
|
|
45
|
+
|
|
46
|
+
/** @type {HTMLIFrameElement} */
|
|
47
|
+
iframeContainerElement.contentDocument.createElement("div");
|
|
38
48
|
containerElement.id = "webpack-dev-server-client-overlay-div";
|
|
39
49
|
containerElement.style.position = "fixed";
|
|
40
50
|
containerElement.style.boxSizing = "border-box";
|
|
@@ -62,7 +72,8 @@ function createContainer() {
|
|
|
62
72
|
closeButtonElement.style.fontWeight = "bold";
|
|
63
73
|
closeButtonElement.style.color = "white";
|
|
64
74
|
closeButtonElement.style.cursor = "pointer";
|
|
65
|
-
closeButtonElement.style.cssFloat = "right";
|
|
75
|
+
closeButtonElement.style.cssFloat = "right"; // @ts-ignore
|
|
76
|
+
|
|
66
77
|
closeButtonElement.style.styleFloat = "right";
|
|
67
78
|
closeButtonElement.addEventListener("click", function () {
|
|
68
79
|
hide();
|
|
@@ -71,16 +82,27 @@ function createContainer() {
|
|
|
71
82
|
containerElement.appendChild(closeButtonElement);
|
|
72
83
|
containerElement.appendChild(document.createElement("br"));
|
|
73
84
|
containerElement.appendChild(document.createElement("br"));
|
|
85
|
+
/** @type {Document} */
|
|
86
|
+
|
|
87
|
+
/** @type {HTMLIFrameElement} */
|
|
74
88
|
iframeContainerElement.contentDocument.body.appendChild(containerElement);
|
|
75
89
|
onLoadQueue.forEach(function (onLoad) {
|
|
76
|
-
onLoad(
|
|
90
|
+
onLoad(
|
|
91
|
+
/** @type {HTMLDivElement} */
|
|
92
|
+
containerElement);
|
|
77
93
|
});
|
|
78
94
|
onLoadQueue = [];
|
|
95
|
+
/** @type {HTMLIFrameElement} */
|
|
96
|
+
|
|
79
97
|
iframeContainerElement.onload = null;
|
|
80
98
|
};
|
|
81
99
|
|
|
82
100
|
document.body.appendChild(iframeContainerElement);
|
|
83
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* @param {(element: HTMLDivElement) => void} callback
|
|
104
|
+
*/
|
|
105
|
+
|
|
84
106
|
|
|
85
107
|
function ensureOverlayExists(callback) {
|
|
86
108
|
if (containerElement) {
|
|
@@ -109,6 +131,12 @@ function hide() {
|
|
|
109
131
|
iframeContainerElement = null;
|
|
110
132
|
containerElement = null;
|
|
111
133
|
}
|
|
134
|
+
/**
|
|
135
|
+
* @param {string} type
|
|
136
|
+
* @param {string | { file?: string, moduleName?: string, loc?: string, message?: string }} item
|
|
137
|
+
* @returns {{ header: string, body: string }}
|
|
138
|
+
*/
|
|
139
|
+
|
|
112
140
|
|
|
113
141
|
function formatProblem(type, item) {
|
|
114
142
|
var header = type === "warning" ? "WARNING" : "ERROR";
|
|
@@ -131,6 +159,11 @@ function formatProblem(type, item) {
|
|
|
131
159
|
};
|
|
132
160
|
} // Compilation with errors (e.g. syntax error or missing modules).
|
|
133
161
|
|
|
162
|
+
/**
|
|
163
|
+
* @param {string} type
|
|
164
|
+
* @param {Array<string | { file?: string, moduleName?: string, loc?: string, message?: string }>} messages
|
|
165
|
+
*/
|
|
166
|
+
|
|
134
167
|
|
|
135
168
|
function show(type, messages) {
|
|
136
169
|
ensureOverlayExists(function () {
|
|
@@ -154,6 +187,8 @@ function show(type, messages) {
|
|
|
154
187
|
entryElement.appendChild(messageTextNode);
|
|
155
188
|
entryElement.appendChild(document.createElement("br"));
|
|
156
189
|
entryElement.appendChild(document.createElement("br"));
|
|
190
|
+
/** @type {HTMLDivElement} */
|
|
191
|
+
|
|
157
192
|
containerElement.appendChild(entryElement);
|
|
158
193
|
});
|
|
159
194
|
});
|
package/client/socket.js
CHANGED
|
@@ -4,20 +4,27 @@ import { log } from "./utils/log.js"; // this WebsocketClient is here as a defau
|
|
|
4
4
|
|
|
5
5
|
/* eslint-disable camelcase */
|
|
6
6
|
|
|
7
|
-
var Client = // eslint-disable-next-line
|
|
8
|
-
typeof __webpack_dev_server_client__ !== "undefined" ?
|
|
9
|
-
typeof __webpack_dev_server_client__.default !== "undefined" ? __webpack_dev_server_client__.default : __webpack_dev_server_client__ : WebSocketClient;
|
|
7
|
+
var Client = // eslint-disable-next-line no-nested-ternary
|
|
8
|
+
typeof __webpack_dev_server_client__ !== "undefined" ? typeof __webpack_dev_server_client__.default !== "undefined" ? __webpack_dev_server_client__.default : __webpack_dev_server_client__ : WebSocketClient;
|
|
10
9
|
/* eslint-enable camelcase */
|
|
11
10
|
|
|
12
11
|
var retries = 0;
|
|
13
12
|
var maxRetries = 10;
|
|
14
13
|
var client = null;
|
|
14
|
+
/**
|
|
15
|
+
* @param {string} url
|
|
16
|
+
* @param {{ [handler: string]: (data?: any, params?: any) => any }} handlers
|
|
17
|
+
* @param {number} [reconnect]
|
|
18
|
+
*/
|
|
15
19
|
|
|
16
20
|
var socket = function initSocket(url, handlers, reconnect) {
|
|
17
21
|
client = new Client(url);
|
|
18
22
|
client.onOpen(function () {
|
|
19
23
|
retries = 0;
|
|
20
|
-
|
|
24
|
+
|
|
25
|
+
if (typeof reconnect !== "undefined") {
|
|
26
|
+
maxRetries = reconnect;
|
|
27
|
+
}
|
|
21
28
|
});
|
|
22
29
|
client.onClose(function () {
|
|
23
30
|
if (retries === 0) {
|
|
@@ -30,20 +37,24 @@ var socket = function initSocket(url, handlers, reconnect) {
|
|
|
30
37
|
if (retries < maxRetries) {
|
|
31
38
|
// Exponentially increase timeout to reconnect.
|
|
32
39
|
// Respectfully copied from the package `got`.
|
|
33
|
-
// eslint-disable-next-line no-
|
|
40
|
+
// eslint-disable-next-line no-restricted-properties
|
|
34
41
|
var retryInMs = 1000 * Math.pow(2, retries) + Math.random() * 100;
|
|
35
42
|
retries += 1;
|
|
36
43
|
log.info("Trying to reconnect...");
|
|
37
44
|
setTimeout(function () {
|
|
38
|
-
socket(url, handlers);
|
|
45
|
+
socket(url, handlers, reconnect);
|
|
39
46
|
}, retryInMs);
|
|
40
47
|
}
|
|
41
48
|
});
|
|
42
|
-
client.onMessage(
|
|
49
|
+
client.onMessage(
|
|
50
|
+
/**
|
|
51
|
+
* @param {any} data
|
|
52
|
+
*/
|
|
53
|
+
function (data) {
|
|
43
54
|
var message = JSON.parse(data);
|
|
44
55
|
|
|
45
56
|
if (handlers[message.type]) {
|
|
46
|
-
handlers[message.type](message.data);
|
|
57
|
+
handlers[message.type](message.data, message.params);
|
|
47
58
|
}
|
|
48
59
|
});
|
|
49
60
|
};
|
|
@@ -1,9 +1,76 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @param {{ protocol?: string, auth?: string, hostname?: string, port?: string, pathname?: string, search?: string, hash?: string, slashes?: boolean }} objURL
|
|
3
|
+
* @returns {string}
|
|
4
|
+
*/
|
|
5
|
+
function format(objURL) {
|
|
6
|
+
var protocol = objURL.protocol || "";
|
|
7
|
+
|
|
8
|
+
if (protocol && protocol.substr(-1) !== ":") {
|
|
9
|
+
protocol += ":";
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
var auth = objURL.auth || "";
|
|
13
|
+
|
|
14
|
+
if (auth) {
|
|
15
|
+
auth = encodeURIComponent(auth);
|
|
16
|
+
auth = auth.replace(/%3A/i, ":");
|
|
17
|
+
auth += "@";
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
var host = "";
|
|
21
|
+
|
|
22
|
+
if (objURL.hostname) {
|
|
23
|
+
host = auth + (objURL.hostname.indexOf(":") === -1 ? objURL.hostname : "[".concat(objURL.hostname, "]"));
|
|
24
|
+
|
|
25
|
+
if (objURL.port) {
|
|
26
|
+
host += ":".concat(objURL.port);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
var pathname = objURL.pathname || "";
|
|
31
|
+
|
|
32
|
+
if (objURL.slashes) {
|
|
33
|
+
host = "//".concat(host || "");
|
|
34
|
+
|
|
35
|
+
if (pathname && pathname.charAt(0) !== "/") {
|
|
36
|
+
pathname = "/".concat(pathname);
|
|
37
|
+
}
|
|
38
|
+
} else if (!host) {
|
|
39
|
+
host = "";
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
var search = objURL.search || "";
|
|
43
|
+
|
|
44
|
+
if (search && search.charAt(0) !== "?") {
|
|
45
|
+
search = "?".concat(search);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
var hash = objURL.hash || "";
|
|
49
|
+
|
|
50
|
+
if (hash && hash.charAt(0) !== "#") {
|
|
51
|
+
hash = "#".concat(hash);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
pathname = pathname.replace(/[?#]/g,
|
|
55
|
+
/**
|
|
56
|
+
* @param {string} match
|
|
57
|
+
* @returns {string}
|
|
58
|
+
*/
|
|
59
|
+
function (match) {
|
|
60
|
+
return encodeURIComponent(match);
|
|
61
|
+
});
|
|
62
|
+
search = search.replace("#", "%23");
|
|
63
|
+
return "".concat(protocol).concat(host).concat(pathname).concat(search).concat(hash);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* @param {URL & { fromCurrentScript?: boolean }} parsedURL
|
|
67
|
+
* @returns {string}
|
|
68
|
+
*/
|
|
69
|
+
|
|
3
70
|
|
|
4
71
|
function createSocketURL(parsedURL) {
|
|
5
72
|
var hostname = parsedURL.hostname; // Node.js module parses it as `::`
|
|
6
|
-
// `new URL(urlString, [
|
|
73
|
+
// `new URL(urlString, [baseURLString])` parses it as '[::]'
|
|
7
74
|
|
|
8
75
|
var isInAddrAny = hostname === "0.0.0.0" || hostname === "::" || hostname === "[::]"; // why do we need this check?
|
|
9
76
|
// hostname n/a for file protocol (example, when using electron, ionic)
|
|
@@ -57,7 +124,7 @@ function createSocketURL(parsedURL) {
|
|
|
57
124
|
socketURLPathname = parsedURL.pathname;
|
|
58
125
|
}
|
|
59
126
|
|
|
60
|
-
return
|
|
127
|
+
return format({
|
|
61
128
|
protocol: socketURLProtocol,
|
|
62
129
|
auth: socketURLAuth,
|
|
63
130
|
hostname: socketURLHostname,
|
package/client/utils/log.js
CHANGED
|
@@ -2,7 +2,12 @@ import logger from "../modules/logger/index.js";
|
|
|
2
2
|
var name = "webpack-dev-server"; // default level is set on the client side, so it does not need
|
|
3
3
|
// to be set by the CLI or API
|
|
4
4
|
|
|
5
|
-
var defaultLevel = "info";
|
|
5
|
+
var defaultLevel = "info"; // options new options, merge with old options
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @param {false | true | "none" | "error" | "warn" | "info" | "log" | "verbose"} level
|
|
9
|
+
* @returns {void}
|
|
10
|
+
*/
|
|
6
11
|
|
|
7
12
|
function setLogLevel(level) {
|
|
8
13
|
logger.configureDefaultLogger({
|
package/client/utils/parseURL.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import url from "url";
|
|
2
1
|
import getCurrentScriptSource from "./getCurrentScriptSource.js";
|
|
2
|
+
/**
|
|
3
|
+
* @param {string} resourceQuery
|
|
4
|
+
* @returns {{ [key: string]: string | boolean }}
|
|
5
|
+
*/
|
|
3
6
|
|
|
4
7
|
function parseURL(resourceQuery) {
|
|
8
|
+
/** @type {{ [key: string]: string }} */
|
|
5
9
|
var options = {};
|
|
6
10
|
|
|
7
11
|
if (typeof resourceQuery === "string" && resourceQuery !== "") {
|
|
@@ -14,25 +18,19 @@ function parseURL(resourceQuery) {
|
|
|
14
18
|
} else {
|
|
15
19
|
// Else, get the url from the <script> this file was called with.
|
|
16
20
|
var scriptSource = getCurrentScriptSource();
|
|
21
|
+
var scriptSourceURL;
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
// The placeholder `baseURL` with `window.location.href`,
|
|
25
|
+
// is to allow parsing of path-relative or protocol-relative URLs,
|
|
26
|
+
// and will have no effect if `scriptSource` is a fully valid URL.
|
|
27
|
+
scriptSourceURL = new URL(scriptSource, self.location.href);
|
|
28
|
+
} catch (error) {// URL parsing failed, do nothing.
|
|
29
|
+
// We will still proceed to see if we can recover using `resourceQuery`
|
|
30
|
+
}
|
|
17
31
|
|
|
18
|
-
if (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
try {
|
|
22
|
-
// The placeholder `baseURL` with `window.location.href`,
|
|
23
|
-
// is to allow parsing of path-relative or protocol-relative URLs,
|
|
24
|
-
// and will have no effect if `scriptSource` is a fully valid URL.
|
|
25
|
-
scriptSourceURL = new URL(scriptSource, self.location.href);
|
|
26
|
-
} catch (error) {// URL parsing failed, do nothing.
|
|
27
|
-
// We will still proceed to see if we can recover using `resourceQuery`
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (scriptSourceURL) {
|
|
31
|
-
options = scriptSourceURL;
|
|
32
|
-
options.fromCurrentScript = true;
|
|
33
|
-
}
|
|
34
|
-
} else {
|
|
35
|
-
options = url.parse(self.location.href, true, true);
|
|
32
|
+
if (scriptSourceURL) {
|
|
33
|
+
options = scriptSourceURL;
|
|
36
34
|
options.fromCurrentScript = true;
|
|
37
35
|
}
|
|
38
36
|
}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
/* global __webpack_hash__ */
|
|
2
1
|
import hotEmitter from "webpack/hot/emitter.js";
|
|
3
2
|
import { log } from "./log.js";
|
|
3
|
+
/** @typedef {import("../index").Options} Options
|
|
4
|
+
/** @typedef {import("../index").Status} Status
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @param {Options} options
|
|
8
|
+
* @param {Status} status
|
|
9
|
+
*/
|
|
4
10
|
|
|
5
11
|
function reloadApp(_ref, status) {
|
|
6
12
|
var hot = _ref.hot,
|
|
@@ -12,11 +18,18 @@ function reloadApp(_ref, status) {
|
|
|
12
18
|
|
|
13
19
|
var currentHash = status.currentHash,
|
|
14
20
|
previousHash = status.previousHash;
|
|
15
|
-
var isInitial = currentHash.indexOf(
|
|
21
|
+
var isInitial = currentHash.indexOf(
|
|
22
|
+
/** @type {string} */
|
|
23
|
+
previousHash) >= 0;
|
|
16
24
|
|
|
17
25
|
if (isInitial) {
|
|
18
26
|
return;
|
|
19
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* @param {Window} rootWindow
|
|
30
|
+
* @param {number} intervalId
|
|
31
|
+
*/
|
|
32
|
+
|
|
20
33
|
|
|
21
34
|
function applyReload(rootWindow, intervalId) {
|
|
22
35
|
clearInterval(intervalId);
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
/* global __resourceQuery WorkerGlobalScope */
|
|
2
2
|
// Send messages to the outside, so plugins can consume it.
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @param {string} type
|
|
6
|
+
* @param {any} [data]
|
|
7
|
+
*/
|
|
3
8
|
function sendMsg(type, data) {
|
|
4
9
|
if (typeof self !== "undefined" && (typeof WorkerGlobalScope === "undefined" || !(self instanceof WorkerGlobalScope))) {
|
|
5
10
|
self.postMessage({
|