webpack-dev-server 4.11.0 → 4.12.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/bin/webpack-dev-server.js +12 -0
- package/client/clients/SockJSClient.js +7 -14
- package/client/clients/WebSocketClient.js +7 -14
- package/client/index.js +41 -69
- package/client/modules/logger/index.js +66 -165
- package/client/modules/sockjs-client/index.js +516 -1166
- package/client/overlay/fsm.js +64 -0
- package/client/overlay/runtime-error.js +31 -0
- package/client/overlay/state-machine.js +95 -0
- package/client/overlay/styles.js +74 -0
- package/client/overlay.js +199 -167
- package/client/socket.js +13 -12
- package/client/utils/createSocketURL.js +20 -36
- package/client/utils/getCurrentScriptSource.js +4 -6
- package/client/utils/log.js +8 -13
- package/client/utils/parseURL.js +3 -8
- package/client/utils/reloadApp.js +9 -18
- package/client/utils/sendMessage.js +1 -2
- package/client/utils/stripAnsi.js +1 -3
- package/lib/Server.js +55 -15
- package/lib/servers/SockJSServer.js +22 -10
- package/package.json +16 -12
- package/types/lib/Server.d.ts +39 -37
package/client/socket.js
CHANGED
|
@@ -1,30 +1,32 @@
|
|
|
1
1
|
/* global __webpack_dev_server_client__ */
|
|
2
|
+
|
|
2
3
|
import WebSocketClient from "./clients/WebSocketClient.js";
|
|
3
|
-
import { log } from "./utils/log.js";
|
|
4
|
+
import { log } from "./utils/log.js";
|
|
4
5
|
|
|
6
|
+
// this WebsocketClient is here as a default fallback, in case the client is not injected
|
|
5
7
|
/* eslint-disable camelcase */
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
var Client =
|
|
9
|
+
// eslint-disable-next-line no-nested-ternary
|
|
8
10
|
typeof __webpack_dev_server_client__ !== "undefined" ? typeof __webpack_dev_server_client__.default !== "undefined" ? __webpack_dev_server_client__.default : __webpack_dev_server_client__ : WebSocketClient;
|
|
9
11
|
/* eslint-enable camelcase */
|
|
10
12
|
|
|
11
13
|
var retries = 0;
|
|
12
|
-
var maxRetries = 10;
|
|
14
|
+
var maxRetries = 10;
|
|
15
|
+
|
|
16
|
+
// Initialized client is exported so external consumers can utilize the same instance
|
|
13
17
|
// It is mutable to enforce singleton
|
|
14
18
|
// eslint-disable-next-line import/no-mutable-exports
|
|
15
|
-
|
|
16
19
|
export var client = null;
|
|
20
|
+
|
|
17
21
|
/**
|
|
18
22
|
* @param {string} url
|
|
19
23
|
* @param {{ [handler: string]: (data?: any, params?: any) => any }} handlers
|
|
20
24
|
* @param {number} [reconnect]
|
|
21
25
|
*/
|
|
22
|
-
|
|
23
26
|
var socket = function initSocket(url, handlers, reconnect) {
|
|
24
27
|
client = new Client(url);
|
|
25
28
|
client.onOpen(function () {
|
|
26
29
|
retries = 0;
|
|
27
|
-
|
|
28
30
|
if (typeof reconnect !== "undefined") {
|
|
29
31
|
maxRetries = reconnect;
|
|
30
32
|
}
|
|
@@ -32,11 +34,12 @@ var socket = function initSocket(url, handlers, reconnect) {
|
|
|
32
34
|
client.onClose(function () {
|
|
33
35
|
if (retries === 0) {
|
|
34
36
|
handlers.close();
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
+
}
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
// Try to reconnect.
|
|
40
|
+
client = null;
|
|
39
41
|
|
|
42
|
+
// After 10 retries stop trying, to prevent logspam.
|
|
40
43
|
if (retries < maxRetries) {
|
|
41
44
|
// Exponentially increase timeout to reconnect.
|
|
42
45
|
// Respectfully copied from the package `got`.
|
|
@@ -55,11 +58,9 @@ var socket = function initSocket(url, handlers, reconnect) {
|
|
|
55
58
|
*/
|
|
56
59
|
function (data) {
|
|
57
60
|
var message = JSON.parse(data);
|
|
58
|
-
|
|
59
61
|
if (handlers[message.type]) {
|
|
60
62
|
handlers[message.type](message.data, message.params);
|
|
61
63
|
}
|
|
62
64
|
});
|
|
63
65
|
};
|
|
64
|
-
|
|
65
66
|
export default socket;
|
|
@@ -4,53 +4,39 @@
|
|
|
4
4
|
*/
|
|
5
5
|
function format(objURL) {
|
|
6
6
|
var protocol = objURL.protocol || "";
|
|
7
|
-
|
|
8
7
|
if (protocol && protocol.substr(-1) !== ":") {
|
|
9
8
|
protocol += ":";
|
|
10
9
|
}
|
|
11
|
-
|
|
12
10
|
var auth = objURL.auth || "";
|
|
13
|
-
|
|
14
11
|
if (auth) {
|
|
15
12
|
auth = encodeURIComponent(auth);
|
|
16
13
|
auth = auth.replace(/%3A/i, ":");
|
|
17
14
|
auth += "@";
|
|
18
15
|
}
|
|
19
|
-
|
|
20
16
|
var host = "";
|
|
21
|
-
|
|
22
17
|
if (objURL.hostname) {
|
|
23
18
|
host = auth + (objURL.hostname.indexOf(":") === -1 ? objURL.hostname : "[".concat(objURL.hostname, "]"));
|
|
24
|
-
|
|
25
19
|
if (objURL.port) {
|
|
26
20
|
host += ":".concat(objURL.port);
|
|
27
21
|
}
|
|
28
22
|
}
|
|
29
|
-
|
|
30
23
|
var pathname = objURL.pathname || "";
|
|
31
|
-
|
|
32
24
|
if (objURL.slashes) {
|
|
33
25
|
host = "//".concat(host || "");
|
|
34
|
-
|
|
35
26
|
if (pathname && pathname.charAt(0) !== "/") {
|
|
36
27
|
pathname = "/".concat(pathname);
|
|
37
28
|
}
|
|
38
29
|
} else if (!host) {
|
|
39
30
|
host = "";
|
|
40
31
|
}
|
|
41
|
-
|
|
42
32
|
var search = objURL.search || "";
|
|
43
|
-
|
|
44
33
|
if (search && search.charAt(0) !== "?") {
|
|
45
34
|
search = "?".concat(search);
|
|
46
35
|
}
|
|
47
|
-
|
|
48
36
|
var hash = objURL.hash || "";
|
|
49
|
-
|
|
50
37
|
if (hash && hash.charAt(0) !== "#") {
|
|
51
38
|
hash = "#".concat(hash);
|
|
52
39
|
}
|
|
53
|
-
|
|
54
40
|
pathname = pathname.replace(/[?#]/g,
|
|
55
41
|
/**
|
|
56
42
|
* @param {string} match
|
|
@@ -62,43 +48,47 @@ function format(objURL) {
|
|
|
62
48
|
search = search.replace("#", "%23");
|
|
63
49
|
return "".concat(protocol).concat(host).concat(pathname).concat(search).concat(hash);
|
|
64
50
|
}
|
|
51
|
+
|
|
65
52
|
/**
|
|
66
53
|
* @param {URL & { fromCurrentScript?: boolean }} parsedURL
|
|
67
54
|
* @returns {string}
|
|
68
55
|
*/
|
|
69
|
-
|
|
70
|
-
|
|
71
56
|
function createSocketURL(parsedURL) {
|
|
72
|
-
var hostname = parsedURL.hostname;
|
|
57
|
+
var hostname = parsedURL.hostname;
|
|
58
|
+
|
|
59
|
+
// Node.js module parses it as `::`
|
|
73
60
|
// `new URL(urlString, [baseURLString])` parses it as '[::]'
|
|
61
|
+
var isInAddrAny = hostname === "0.0.0.0" || hostname === "::" || hostname === "[::]";
|
|
74
62
|
|
|
75
|
-
|
|
63
|
+
// why do we need this check?
|
|
76
64
|
// hostname n/a for file protocol (example, when using electron, ionic)
|
|
77
65
|
// see: https://github.com/webpack/webpack-dev-server/pull/384
|
|
78
|
-
|
|
79
66
|
if (isInAddrAny && self.location.hostname && self.location.protocol.indexOf("http") === 0) {
|
|
80
67
|
hostname = self.location.hostname;
|
|
81
68
|
}
|
|
69
|
+
var socketURLProtocol = parsedURL.protocol || self.location.protocol;
|
|
82
70
|
|
|
83
|
-
|
|
84
|
-
|
|
71
|
+
// When https is used in the app, secure web sockets are always necessary because the browser doesn't accept non-secure web sockets.
|
|
85
72
|
if (socketURLProtocol === "auto:" || hostname && isInAddrAny && self.location.protocol === "https:") {
|
|
86
73
|
socketURLProtocol = self.location.protocol;
|
|
87
74
|
}
|
|
88
|
-
|
|
89
75
|
socketURLProtocol = socketURLProtocol.replace(/^(?:http|.+-extension|file)/i, "ws");
|
|
90
|
-
var socketURLAuth = "";
|
|
91
|
-
// Parse authentication credentials in case we need them
|
|
76
|
+
var socketURLAuth = "";
|
|
92
77
|
|
|
78
|
+
// `new URL(urlString, [baseURLstring])` doesn't have `auth` property
|
|
79
|
+
// Parse authentication credentials in case we need them
|
|
93
80
|
if (parsedURL.username) {
|
|
94
|
-
socketURLAuth = parsedURL.username;
|
|
95
|
-
// we only include password if the username is not empty.
|
|
81
|
+
socketURLAuth = parsedURL.username;
|
|
96
82
|
|
|
83
|
+
// Since HTTP basic authentication does not allow empty username,
|
|
84
|
+
// we only include password if the username is not empty.
|
|
97
85
|
if (parsedURL.password) {
|
|
98
86
|
// Result: <username>:<password>
|
|
99
87
|
socketURLAuth = socketURLAuth.concat(":", parsedURL.password);
|
|
100
88
|
}
|
|
101
|
-
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// In case the host is a raw IPv6 address, it can be enclosed in
|
|
102
92
|
// the brackets as the brackets are needed in the final URL string.
|
|
103
93
|
// Need to remove those as url.format blindly adds its own set of brackets
|
|
104
94
|
// if the host string contains colons. That would lead to non-working
|
|
@@ -106,24 +96,19 @@ function createSocketURL(parsedURL) {
|
|
|
106
96
|
//
|
|
107
97
|
// All of these web socket url params are optionally passed in through resourceQuery,
|
|
108
98
|
// so we need to fall back to the default if they are not provided
|
|
109
|
-
|
|
110
|
-
|
|
111
99
|
var socketURLHostname = (hostname || self.location.hostname || "localhost").replace(/^\[(.*)\]$/, "$1");
|
|
112
100
|
var socketURLPort = parsedURL.port;
|
|
113
|
-
|
|
114
101
|
if (!socketURLPort || socketURLPort === "0") {
|
|
115
102
|
socketURLPort = self.location.port;
|
|
116
|
-
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// If path is provided it'll be passed in via the resourceQuery as a
|
|
117
106
|
// query param so it has to be parsed out of the querystring in order for the
|
|
118
107
|
// client to open the socket to the correct location.
|
|
119
|
-
|
|
120
|
-
|
|
121
108
|
var socketURLPathname = "/ws";
|
|
122
|
-
|
|
123
109
|
if (parsedURL.pathname && !parsedURL.fromCurrentScript) {
|
|
124
110
|
socketURLPathname = parsedURL.pathname;
|
|
125
111
|
}
|
|
126
|
-
|
|
127
112
|
return format({
|
|
128
113
|
protocol: socketURLProtocol,
|
|
129
114
|
auth: socketURLAuth,
|
|
@@ -133,5 +118,4 @@ function createSocketURL(parsedURL) {
|
|
|
133
118
|
slashes: true
|
|
134
119
|
});
|
|
135
120
|
}
|
|
136
|
-
|
|
137
121
|
export default createSocketURL;
|
|
@@ -6,21 +6,19 @@ function getCurrentScriptSource() {
|
|
|
6
6
|
// but is not supported in all browsers.
|
|
7
7
|
if (document.currentScript) {
|
|
8
8
|
return document.currentScript.getAttribute("src");
|
|
9
|
-
}
|
|
10
|
-
|
|
9
|
+
}
|
|
11
10
|
|
|
11
|
+
// Fallback to getting all scripts running in the document.
|
|
12
12
|
var scriptElements = document.scripts || [];
|
|
13
13
|
var scriptElementsWithSrc = Array.prototype.filter.call(scriptElements, function (element) {
|
|
14
14
|
return element.getAttribute("src");
|
|
15
15
|
});
|
|
16
|
-
|
|
17
16
|
if (scriptElementsWithSrc.length > 0) {
|
|
18
17
|
var currentScript = scriptElementsWithSrc[scriptElementsWithSrc.length - 1];
|
|
19
18
|
return currentScript.getAttribute("src");
|
|
20
|
-
}
|
|
21
|
-
|
|
19
|
+
}
|
|
22
20
|
|
|
21
|
+
// Fail as there was no script to use.
|
|
23
22
|
throw new Error("[webpack-dev-server] Failed to get current script source.");
|
|
24
23
|
}
|
|
25
|
-
|
|
26
24
|
export default getCurrentScriptSource;
|
package/client/utils/log.js
CHANGED
|
@@ -1,40 +1,35 @@
|
|
|
1
1
|
import logger from "../modules/logger/index.js";
|
|
2
|
-
var name = "webpack-dev-server";
|
|
2
|
+
var name = "webpack-dev-server";
|
|
3
|
+
// default level is set on the client side, so it does not need
|
|
3
4
|
// to be set by the CLI or API
|
|
5
|
+
var defaultLevel = "info";
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
+
// options new options, merge with old options
|
|
7
8
|
/**
|
|
8
9
|
* @param {false | true | "none" | "error" | "warn" | "info" | "log" | "verbose"} level
|
|
9
10
|
* @returns {void}
|
|
10
11
|
*/
|
|
11
|
-
|
|
12
12
|
function setLogLevel(level) {
|
|
13
13
|
logger.configureDefaultLogger({
|
|
14
14
|
level: level
|
|
15
15
|
});
|
|
16
16
|
}
|
|
17
|
-
|
|
18
17
|
setLogLevel(defaultLevel);
|
|
19
18
|
var log = logger.getLogger(name);
|
|
20
|
-
|
|
21
19
|
var logEnabledFeatures = function logEnabledFeatures(features) {
|
|
22
20
|
var enabledFeatures = Object.keys(features);
|
|
23
|
-
|
|
24
21
|
if (!features || enabledFeatures.length === 0) {
|
|
25
22
|
return;
|
|
26
23
|
}
|
|
24
|
+
var logString = "Server started:";
|
|
27
25
|
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
// Server started: Hot Module Replacement enabled, Live Reloading enabled, Overlay disabled.
|
|
30
27
|
for (var i = 0; i < enabledFeatures.length; i++) {
|
|
31
28
|
var key = enabledFeatures[i];
|
|
32
29
|
logString += " ".concat(key, " ").concat(features[key] ? "enabled" : "disabled", ",");
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
30
|
+
}
|
|
31
|
+
// replace last comma with a period
|
|
36
32
|
logString = logString.slice(0, -1).concat(".");
|
|
37
33
|
log.info(logString);
|
|
38
34
|
};
|
|
39
|
-
|
|
40
35
|
export { log, logEnabledFeatures, setLogLevel };
|
package/client/utils/parseURL.js
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import getCurrentScriptSource from "./getCurrentScriptSource.js";
|
|
2
|
+
|
|
2
3
|
/**
|
|
3
4
|
* @param {string} resourceQuery
|
|
4
5
|
* @returns {{ [key: string]: string | boolean }}
|
|
5
6
|
*/
|
|
6
|
-
|
|
7
7
|
function parseURL(resourceQuery) {
|
|
8
8
|
/** @type {{ [key: string]: string }} */
|
|
9
9
|
var options = {};
|
|
10
|
-
|
|
11
10
|
if (typeof resourceQuery === "string" && resourceQuery !== "") {
|
|
12
11
|
var searchParams = resourceQuery.slice(1).split("&");
|
|
13
|
-
|
|
14
12
|
for (var i = 0; i < searchParams.length; i++) {
|
|
15
13
|
var pair = searchParams[i].split("=");
|
|
16
14
|
options[pair[0]] = decodeURIComponent(pair[1]);
|
|
@@ -19,23 +17,20 @@ function parseURL(resourceQuery) {
|
|
|
19
17
|
// Else, get the url from the <script> this file was called with.
|
|
20
18
|
var scriptSource = getCurrentScriptSource();
|
|
21
19
|
var scriptSourceURL;
|
|
22
|
-
|
|
23
20
|
try {
|
|
24
21
|
// The placeholder `baseURL` with `window.location.href`,
|
|
25
22
|
// is to allow parsing of path-relative or protocol-relative URLs,
|
|
26
23
|
// and will have no effect if `scriptSource` is a fully valid URL.
|
|
27
24
|
scriptSourceURL = new URL(scriptSource, self.location.href);
|
|
28
|
-
} catch (error) {
|
|
25
|
+
} catch (error) {
|
|
26
|
+
// URL parsing failed, do nothing.
|
|
29
27
|
// We will still proceed to see if we can recover using `resourceQuery`
|
|
30
28
|
}
|
|
31
|
-
|
|
32
29
|
if (scriptSourceURL) {
|
|
33
30
|
options = scriptSourceURL;
|
|
34
31
|
options.fromCurrentScript = true;
|
|
35
32
|
}
|
|
36
33
|
}
|
|
37
|
-
|
|
38
34
|
return options;
|
|
39
35
|
}
|
|
40
|
-
|
|
41
36
|
export default parseURL;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import hotEmitter from "webpack/hot/emitter.js";
|
|
2
2
|
import { log } from "./log.js";
|
|
3
|
+
|
|
3
4
|
/** @typedef {import("../index").Options} Options
|
|
4
5
|
/** @typedef {import("../index").Status} Status
|
|
5
6
|
|
|
@@ -7,59 +8,50 @@ import { log } from "./log.js";
|
|
|
7
8
|
* @param {Options} options
|
|
8
9
|
* @param {Status} status
|
|
9
10
|
*/
|
|
10
|
-
|
|
11
11
|
function reloadApp(_ref, status) {
|
|
12
12
|
var hot = _ref.hot,
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
liveReload = _ref.liveReload;
|
|
15
14
|
if (status.isUnloading) {
|
|
16
15
|
return;
|
|
17
16
|
}
|
|
18
|
-
|
|
19
17
|
var currentHash = status.currentHash,
|
|
20
|
-
|
|
21
|
-
var isInitial = currentHash.indexOf(
|
|
22
|
-
/** @type {string} */
|
|
23
|
-
previousHash) >= 0;
|
|
24
|
-
|
|
18
|
+
previousHash = status.previousHash;
|
|
19
|
+
var isInitial = currentHash.indexOf( /** @type {string} */previousHash) >= 0;
|
|
25
20
|
if (isInitial) {
|
|
26
21
|
return;
|
|
27
22
|
}
|
|
23
|
+
|
|
28
24
|
/**
|
|
29
25
|
* @param {Window} rootWindow
|
|
30
26
|
* @param {number} intervalId
|
|
31
27
|
*/
|
|
32
|
-
|
|
33
|
-
|
|
34
28
|
function applyReload(rootWindow, intervalId) {
|
|
35
29
|
clearInterval(intervalId);
|
|
36
30
|
log.info("App updated. Reloading...");
|
|
37
31
|
rootWindow.location.reload();
|
|
38
32
|
}
|
|
39
|
-
|
|
40
33
|
var search = self.location.search.toLowerCase();
|
|
41
34
|
var allowToHot = search.indexOf("webpack-dev-server-hot=false") === -1;
|
|
42
35
|
var allowToLiveReload = search.indexOf("webpack-dev-server-live-reload=false") === -1;
|
|
43
|
-
|
|
44
36
|
if (hot && allowToHot) {
|
|
45
37
|
log.info("App hot update...");
|
|
46
38
|
hotEmitter.emit("webpackHotUpdate", status.currentHash);
|
|
47
|
-
|
|
48
39
|
if (typeof self !== "undefined" && self.window) {
|
|
49
40
|
// broadcast update to window
|
|
50
41
|
self.postMessage("webpackHotUpdate".concat(status.currentHash), "*");
|
|
51
42
|
}
|
|
52
|
-
}
|
|
43
|
+
}
|
|
44
|
+
// allow refreshing the page only if liveReload isn't disabled
|
|
53
45
|
else if (liveReload && allowToLiveReload) {
|
|
54
|
-
var rootWindow = self;
|
|
46
|
+
var rootWindow = self;
|
|
55
47
|
|
|
48
|
+
// use parent window for reload (in case we're in an iframe with no valid src)
|
|
56
49
|
var intervalId = self.setInterval(function () {
|
|
57
50
|
if (rootWindow.location.protocol !== "about:") {
|
|
58
51
|
// reload immediately if protocol is valid
|
|
59
52
|
applyReload(rootWindow, intervalId);
|
|
60
53
|
} else {
|
|
61
54
|
rootWindow = rootWindow.parent;
|
|
62
|
-
|
|
63
55
|
if (rootWindow.parent === rootWindow) {
|
|
64
56
|
// if parent equals current window we've reached the root which would continue forever, so trigger a reload anyways
|
|
65
57
|
applyReload(rootWindow, intervalId);
|
|
@@ -68,5 +60,4 @@ function reloadApp(_ref, status) {
|
|
|
68
60
|
});
|
|
69
61
|
}
|
|
70
62
|
}
|
|
71
|
-
|
|
72
63
|
export default reloadApp;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* global __resourceQuery WorkerGlobalScope */
|
|
2
|
-
// Send messages to the outside, so plugins can consume it.
|
|
3
2
|
|
|
3
|
+
// Send messages to the outside, so plugins can consume it.
|
|
4
4
|
/**
|
|
5
5
|
* @param {string} type
|
|
6
6
|
* @param {any} [data]
|
|
@@ -13,5 +13,4 @@ function sendMsg(type, data) {
|
|
|
13
13
|
}, "*");
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
-
|
|
17
16
|
export default sendMsg;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
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
|
+
|
|
2
3
|
/**
|
|
3
4
|
*
|
|
4
5
|
* Strip [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) from a string.
|
|
@@ -8,13 +9,10 @@ var ansiRegex = new RegExp(["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\
|
|
|
8
9
|
* @param {string} string
|
|
9
10
|
* @return {string}
|
|
10
11
|
*/
|
|
11
|
-
|
|
12
12
|
function stripAnsi(string) {
|
|
13
13
|
if (typeof string !== "string") {
|
|
14
14
|
throw new TypeError("Expected a `string`, got `".concat(typeof string, "`"));
|
|
15
15
|
}
|
|
16
|
-
|
|
17
16
|
return string.replace(ansiRegex, "");
|
|
18
17
|
}
|
|
19
|
-
|
|
20
18
|
export default stripAnsi;
|
package/lib/Server.js
CHANGED
|
@@ -451,6 +451,45 @@ class Server {
|
|
|
451
451
|
return path.resolve(dir, "node_modules/.cache/webpack-dev-server");
|
|
452
452
|
}
|
|
453
453
|
|
|
454
|
+
/**
|
|
455
|
+
* @private
|
|
456
|
+
* @param {Compiler} compiler
|
|
457
|
+
* @returns bool
|
|
458
|
+
*/
|
|
459
|
+
static isWebTarget(compiler) {
|
|
460
|
+
// TODO improve for the next major version - we should store `web` and other targets in `compiler.options.environment`
|
|
461
|
+
if (
|
|
462
|
+
compiler.options.externalsPresets &&
|
|
463
|
+
compiler.options.externalsPresets.web
|
|
464
|
+
) {
|
|
465
|
+
return true;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
if (
|
|
469
|
+
compiler.options.resolve.conditionNames &&
|
|
470
|
+
compiler.options.resolve.conditionNames.includes("browser")
|
|
471
|
+
) {
|
|
472
|
+
return true;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
const webTargets = [
|
|
476
|
+
"web",
|
|
477
|
+
"webworker",
|
|
478
|
+
"electron-preload",
|
|
479
|
+
"electron-renderer",
|
|
480
|
+
"node-webkit",
|
|
481
|
+
// eslint-disable-next-line no-undefined
|
|
482
|
+
undefined,
|
|
483
|
+
null,
|
|
484
|
+
];
|
|
485
|
+
|
|
486
|
+
if (Array.isArray(compiler.options.target)) {
|
|
487
|
+
return compiler.options.target.some((r) => webTargets.includes(r));
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
return webTargets.includes(/** @type {string} */ (compiler.options.target));
|
|
491
|
+
}
|
|
492
|
+
|
|
454
493
|
/**
|
|
455
494
|
* @private
|
|
456
495
|
* @param {Compiler} compiler
|
|
@@ -460,21 +499,9 @@ class Server {
|
|
|
460
499
|
* @type {string[]}
|
|
461
500
|
*/
|
|
462
501
|
const additionalEntries = [];
|
|
502
|
+
const isWebTarget = Server.isWebTarget(compiler);
|
|
463
503
|
|
|
464
|
-
|
|
465
|
-
? compiler.options.externalsPresets.web
|
|
466
|
-
: [
|
|
467
|
-
"web",
|
|
468
|
-
"webworker",
|
|
469
|
-
"electron-preload",
|
|
470
|
-
"electron-renderer",
|
|
471
|
-
"node-webkit",
|
|
472
|
-
// eslint-disable-next-line no-undefined
|
|
473
|
-
undefined,
|
|
474
|
-
null,
|
|
475
|
-
].includes(/** @type {string} */ (compiler.options.target));
|
|
476
|
-
|
|
477
|
-
// TODO maybe empty empty client
|
|
504
|
+
// TODO maybe empty client
|
|
478
505
|
if (this.options.client && isWebTarget) {
|
|
479
506
|
let webSocketURLStr = "";
|
|
480
507
|
|
|
@@ -1133,7 +1160,7 @@ class Server {
|
|
|
1133
1160
|
|
|
1134
1161
|
if (
|
|
1135
1162
|
!(/** @type {ServerOptions} */ (options.server.options).key) ||
|
|
1136
|
-
/** @type {ServerOptions} */ (
|
|
1163
|
+
!(/** @type {ServerOptions} */ (options.server.options).cert)
|
|
1137
1164
|
) {
|
|
1138
1165
|
const certificateDir = Server.findCacheDir();
|
|
1139
1166
|
const certificatePath = path.join(certificateDir, "server.pem");
|
|
@@ -2006,6 +2033,19 @@ class Server {
|
|
|
2006
2033
|
}
|
|
2007
2034
|
);
|
|
2008
2035
|
|
|
2036
|
+
/** @type {import("express").Application} */
|
|
2037
|
+
(app).get("/webpack-dev-server/open-editor", (req, res) => {
|
|
2038
|
+
const fileName = req.query.fileName;
|
|
2039
|
+
|
|
2040
|
+
if (typeof fileName === "string") {
|
|
2041
|
+
// @ts-ignore
|
|
2042
|
+
const launchEditor = require("launch-editor");
|
|
2043
|
+
launchEditor(fileName);
|
|
2044
|
+
}
|
|
2045
|
+
|
|
2046
|
+
res.end();
|
|
2047
|
+
});
|
|
2048
|
+
|
|
2009
2049
|
/** @type {import("express").Application} */
|
|
2010
2050
|
(app).get(
|
|
2011
2051
|
"/webpack-dev-server",
|
|
@@ -41,9 +41,28 @@ module.exports = class SockJSServer extends BaseServer {
|
|
|
41
41
|
constructor(server) {
|
|
42
42
|
super(server);
|
|
43
43
|
|
|
44
|
+
const webSocketServerOptions =
|
|
45
|
+
/** @type {NonNullable<WebSocketServerConfiguration["options"]>} */
|
|
46
|
+
(
|
|
47
|
+
/** @type {WebSocketServerConfiguration} */
|
|
48
|
+
(this.server.options.webSocketServer).options
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @param {NonNullable<WebSocketServerConfiguration["options"]>} options
|
|
53
|
+
* @returns {string}
|
|
54
|
+
*/
|
|
55
|
+
const getSockjsUrl = (options) => {
|
|
56
|
+
if (typeof options.sockjsUrl !== "undefined") {
|
|
57
|
+
return options.sockjsUrl;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return "/__webpack_dev_server__/sockjs.bundle.js";
|
|
61
|
+
};
|
|
62
|
+
|
|
44
63
|
this.implementation = sockjs.createServer({
|
|
45
64
|
// Use provided up-to-date sockjs-client
|
|
46
|
-
sockjs_url:
|
|
65
|
+
sockjs_url: getSockjsUrl(webSocketServerOptions),
|
|
47
66
|
// Default logger is very annoy. Limit useless logs.
|
|
48
67
|
/**
|
|
49
68
|
* @param {string} severity
|
|
@@ -73,15 +92,8 @@ module.exports = class SockJSServer extends BaseServer {
|
|
|
73
92
|
};
|
|
74
93
|
|
|
75
94
|
const options = {
|
|
76
|
-
|
|
77
|
-
(
|
|
78
|
-
prefix: getPrefix(
|
|
79
|
-
/** @type {NonNullable<WebSocketServerConfiguration["options"]>} */
|
|
80
|
-
(
|
|
81
|
-
/** @type {WebSocketServerConfiguration} */
|
|
82
|
-
(this.server.options.webSocketServer).options
|
|
83
|
-
)
|
|
84
|
-
),
|
|
95
|
+
...webSocketServerOptions,
|
|
96
|
+
prefix: getPrefix(webSocketServerOptions),
|
|
85
97
|
};
|
|
86
98
|
|
|
87
99
|
this.implementation.installHandlers(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "webpack-dev-server",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.12.0",
|
|
4
4
|
"description": "Serves a webpack app. Updates the browser on changes.",
|
|
5
5
|
"bin": "bin/webpack-dev-server.js",
|
|
6
6
|
"main": "lib/Server.js",
|
|
@@ -63,29 +63,32 @@
|
|
|
63
63
|
"html-entities": "^2.3.2",
|
|
64
64
|
"http-proxy-middleware": "^2.0.3",
|
|
65
65
|
"ipaddr.js": "^2.0.1",
|
|
66
|
+
"launch-editor": "^2.6.0",
|
|
66
67
|
"open": "^8.0.9",
|
|
67
68
|
"p-retry": "^4.5.0",
|
|
68
69
|
"rimraf": "^3.0.2",
|
|
69
70
|
"schema-utils": "^4.0.0",
|
|
70
|
-
"selfsigned": "^2.
|
|
71
|
+
"selfsigned": "^2.1.1",
|
|
71
72
|
"serve-index": "^1.9.1",
|
|
72
73
|
"sockjs": "^0.3.24",
|
|
73
74
|
"spdy": "^4.0.2",
|
|
74
75
|
"webpack-dev-middleware": "^5.3.1",
|
|
75
|
-
"ws": "^8.
|
|
76
|
+
"ws": "^8.13.0"
|
|
76
77
|
},
|
|
77
78
|
"devDependencies": {
|
|
78
79
|
"@babel/cli": "^7.17.3",
|
|
79
|
-
"@babel/core": "^7.
|
|
80
|
+
"@babel/core": "^7.20.2",
|
|
80
81
|
"@babel/eslint-parser": "^7.17.0",
|
|
81
82
|
"@babel/plugin-transform-object-assign": "^7.14.5",
|
|
82
83
|
"@babel/plugin-transform-runtime": "^7.17.0",
|
|
83
|
-
"@babel/preset-env": "^7.
|
|
84
|
-
"@babel/runtime": "^7.
|
|
84
|
+
"@babel/preset-env": "^7.20.2",
|
|
85
|
+
"@babel/runtime": "^7.20.1",
|
|
85
86
|
"@commitlint/cli": "^16.2.3",
|
|
86
87
|
"@commitlint/config-conventional": "^16.2.1",
|
|
87
88
|
"@types/compression": "^1.7.2",
|
|
88
89
|
"@types/default-gateway": "^3.0.1",
|
|
90
|
+
"@types/node": "^18.11.9",
|
|
91
|
+
"@types/node-forge": "^1.3.1",
|
|
89
92
|
"@types/rimraf": "^3.0.2",
|
|
90
93
|
"@types/sockjs-client": "^1.5.1",
|
|
91
94
|
"@types/trusted-types": "^2.0.2",
|
|
@@ -95,7 +98,7 @@
|
|
|
95
98
|
"body-parser": "^1.19.2",
|
|
96
99
|
"core-js": "^3.21.1",
|
|
97
100
|
"css-loader": "^5.2.4",
|
|
98
|
-
"eslint": "^8.
|
|
101
|
+
"eslint": "^8.28.0",
|
|
99
102
|
"eslint-config-prettier": "^8.4.0",
|
|
100
103
|
"eslint-config-webpack": "^1.2.5",
|
|
101
104
|
"eslint-plugin-import": "^2.23.2",
|
|
@@ -110,10 +113,10 @@
|
|
|
110
113
|
"less": "^4.1.1",
|
|
111
114
|
"less-loader": "^7.3.0",
|
|
112
115
|
"lint-staged": "^12.3.4",
|
|
113
|
-
"marked": "^4.
|
|
114
|
-
"memfs": "^3.
|
|
116
|
+
"marked": "^4.2.3",
|
|
117
|
+
"memfs": "^3.4.12",
|
|
115
118
|
"npm-run-all": "^4.1.5",
|
|
116
|
-
"prettier": "^2.
|
|
119
|
+
"prettier": "^2.8.0",
|
|
117
120
|
"puppeteer": "^13.4.1",
|
|
118
121
|
"require-from-string": "^2.0.2",
|
|
119
122
|
"rimraf": "^3.0.2",
|
|
@@ -123,9 +126,10 @@
|
|
|
123
126
|
"style-loader": "^2.0.0",
|
|
124
127
|
"supertest": "^6.1.3",
|
|
125
128
|
"tcp-port-used": "^1.0.2",
|
|
126
|
-
"typescript": "^4.
|
|
129
|
+
"typescript": "^4.9.3",
|
|
127
130
|
"url-loader": "^4.1.1",
|
|
128
|
-
"
|
|
131
|
+
"wait-for-expect": "^3.0.2",
|
|
132
|
+
"webpack": "^5.76.1",
|
|
129
133
|
"webpack-cli": "^4.7.2",
|
|
130
134
|
"webpack-merge": "^5.8.0"
|
|
131
135
|
},
|