Skip to content

Commit 216e3cb

Browse files
authored
feat: allow to configure more client options via resource URL (#4274)
1 parent cffffba commit 216e3cb

File tree

50 files changed

+854
-1187
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+854
-1187
lines changed

client-src/index.js

+34-8
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import stripAnsi from "./utils/stripAnsi.js";
55
import parseURL from "./utils/parseURL.js";
66
import socket from "./socket.js";
77
import { formatProblem, show, hide } from "./overlay.js";
8-
import { log, setLogLevel } from "./utils/log.js";
8+
import { log, logEnabledFeatures, setLogLevel } from "./utils/log.js";
99
import sendMessage from "./utils/sendMessage.js";
1010
import reloadApp from "./utils/reloadApp.js";
1111
import createSocketURL from "./utils/createSocketURL.js";
@@ -46,16 +46,44 @@ const options = {
4646
};
4747
const parsedResourceQuery = parseURL(__resourceQuery);
4848

49+
const enabledFeatures = {
50+
"Hot Module Replacement": false,
51+
"Live Reloading": false,
52+
Progress: false,
53+
Overlay: false,
54+
};
55+
4956
if (parsedResourceQuery.hot === "true") {
5057
options.hot = true;
51-
52-
log.info("Hot Module Replacement enabled.");
58+
enabledFeatures["Hot Module Replacement"] = true;
5359
}
5460

5561
if (parsedResourceQuery["live-reload"] === "true") {
5662
options.liveReload = true;
63+
enabledFeatures["Live Reloading"] = true;
64+
}
5765

58-
log.info("Live Reloading enabled.");
66+
if (parsedResourceQuery.progress === "true") {
67+
options.progress = true;
68+
enabledFeatures.Progress = true;
69+
}
70+
71+
if (parsedResourceQuery.overlay) {
72+
try {
73+
options.overlay = JSON.parse(parsedResourceQuery.overlay);
74+
} catch (e) {
75+
log.error("Error parsing overlay options from resource query:", e);
76+
}
77+
78+
// Fill in default "true" params for partially-specified objects.
79+
if (typeof options.overlay === "object") {
80+
options.overlay = {
81+
errors: true,
82+
warnings: true,
83+
...options.overlay,
84+
};
85+
}
86+
enabledFeatures.Overlay = true;
5987
}
6088

6189
if (parsedResourceQuery.logging) {
@@ -66,6 +94,8 @@ if (typeof parsedResourceQuery.reconnect !== "undefined") {
6694
options.reconnect = Number(parsedResourceQuery.reconnect);
6795
}
6896

97+
logEnabledFeatures(enabledFeatures);
98+
6999
/**
70100
* @param {string} level
71101
*/
@@ -92,17 +122,13 @@ const onSocketMessage = {
92122
}
93123

94124
options.hot = true;
95-
96-
log.info("Hot Module Replacement enabled.");
97125
},
98126
liveReload() {
99127
if (parsedResourceQuery["live-reload"] === "false") {
100128
return;
101129
}
102130

103131
options.liveReload = true;
104-
105-
log.info("Live Reloading enabled.");
106132
},
107133
invalid() {
108134
log.info("App updated. Recompiling...");

client-src/utils/log.js

+19-1
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,22 @@ setLogLevel(defaultLevel);
1818

1919
const log = logger.getLogger(name);
2020

21-
export { log, setLogLevel };
21+
const logEnabledFeatures = (features) => {
22+
const enabledFeatures = Object.entries(features);
23+
if (!features || enabledFeatures.length === 0) {
24+
return;
25+
}
26+
27+
let logString = "Server started:";
28+
29+
// Server started: Hot Module Replacement enabled, Live Reloading enabled, Overlay disabled.
30+
for (const [key, value] of Object.entries(features)) {
31+
logString += ` ${key} ${value ? "enabled" : "disabled"},`;
32+
}
33+
// replace last comma with a period
34+
logString = logString.slice(0, -1).concat(".");
35+
36+
log.info(logString);
37+
};
38+
39+
export { log, logEnabledFeatures, setLogLevel };

lib/Server.js

+21
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,19 @@ class Server {
597597
searchParams.set("logging", client.logging);
598598
}
599599

600+
if (typeof client.progress !== "undefined") {
601+
searchParams.set("progress", String(client.progress));
602+
}
603+
604+
if (typeof client.overlay !== "undefined") {
605+
searchParams.set(
606+
"overlay",
607+
typeof client.overlay === "boolean"
608+
? String(client.overlay)
609+
: JSON.stringify(client.overlay)
610+
);
611+
}
612+
600613
if (typeof client.reconnect !== "undefined") {
601614
searchParams.set(
602615
"reconnect",
@@ -606,6 +619,14 @@ class Server {
606619
);
607620
}
608621

622+
if (typeof this.options.hot !== "undefined") {
623+
searchParams.set("hot", String(this.options.hot));
624+
}
625+
626+
if (typeof this.options.liveReload !== "undefined") {
627+
searchParams.set("live-reload", String(this.options.liveReload));
628+
}
629+
609630
webSocketURLStr = searchParams.toString();
610631
}
611632

test/client/__snapshots__/index.test.js.snap.webpack4

-4
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@ exports[`index should run onSocketMessage.close 2`] = `"Close"`;
1414

1515
exports[`index should run onSocketMessage.error 1`] = `"error!!"`;
1616

17-
exports[`index should run onSocketMessage.hot 1`] = `"Hot Module Replacement enabled."`;
18-
19-
exports[`index should run onSocketMessage.liveReload 1`] = `"Live Reloading enabled."`;
20-
2117
exports[`index should run onSocketMessage.ok 1`] = `"Ok"`;
2218

2319
exports[`index should run onSocketMessage.ok 2`] = `

test/client/__snapshots__/index.test.js.snap.webpack5

-4
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@ exports[`index should run onSocketMessage.close 2`] = `"Close"`;
1414

1515
exports[`index should run onSocketMessage.error 1`] = `"error!!"`;
1616

17-
exports[`index should run onSocketMessage.hot 1`] = `"Hot Module Replacement enabled."`;
18-
19-
exports[`index should run onSocketMessage.liveReload 1`] = `"Live Reloading enabled."`;
20-
2117
exports[`index should run onSocketMessage.ok 1`] = `"Ok"`;
2218

2319
exports[`index should run onSocketMessage.ok 2`] = `

test/client/index.test.js

+57-14
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ describe("index", () => {
2525
warn: jest.fn(),
2626
error: jest.fn(),
2727
},
28+
logEnabledFeatures: jest.fn(),
2829
setLogLevel: jest.fn(),
2930
});
3031

@@ -83,18 +84,6 @@ describe("index", () => {
8384
expect(socket.mock.calls[0]).toMatchSnapshot();
8485
});
8586

86-
test("should run onSocketMessage.hot", () => {
87-
onSocketMessage.hot();
88-
89-
expect(log.log.info.mock.calls[0][0]).toMatchSnapshot();
90-
});
91-
92-
test("should run onSocketMessage.liveReload", () => {
93-
onSocketMessage.liveReload();
94-
95-
expect(log.log.info.mock.calls[0][0]).toMatchSnapshot();
96-
});
97-
9887
test("should run onSocketMessage['still-ok']", () => {
9988
onSocketMessage["still-ok"]();
10089

@@ -207,6 +196,60 @@ describe("index", () => {
207196
expect(overlay.show).toBeCalled();
208197
});
209198

199+
test("should parse overlay options from resource query", () => {
200+
jest.isolateModules(() => {
201+
// Pass JSON config with warnings disabled
202+
global.__resourceQuery = `?overlay=${encodeURIComponent(
203+
`{"warnings": false}`
204+
)}`;
205+
overlay.show.mockReset();
206+
socket.mockReset();
207+
jest.unmock("../../client-src/utils/parseURL.js");
208+
require("../../client-src");
209+
onSocketMessage = socket.mock.calls[0][1];
210+
211+
onSocketMessage.warnings(["warn1"]);
212+
expect(overlay.show).not.toBeCalled();
213+
214+
onSocketMessage.errors(["error1"]);
215+
expect(overlay.show).toBeCalledTimes(1);
216+
});
217+
218+
jest.isolateModules(() => {
219+
// Pass JSON config with errors disabled
220+
global.__resourceQuery = `?overlay=${encodeURIComponent(
221+
`{"errors": false}`
222+
)}`;
223+
overlay.show.mockReset();
224+
socket.mockReset();
225+
jest.unmock("../../client-src/utils/parseURL.js");
226+
require("../../client-src");
227+
onSocketMessage = socket.mock.calls[0][1];
228+
229+
onSocketMessage.errors(["error1"]);
230+
expect(overlay.show).not.toBeCalled();
231+
232+
onSocketMessage.warnings(["warn1"]);
233+
expect(overlay.show).toBeCalledTimes(1);
234+
});
235+
236+
jest.isolateModules(() => {
237+
// Use simple boolean
238+
global.__resourceQuery = "?overlay=true";
239+
jest.unmock("../../client-src/utils/parseURL.js");
240+
socket.mockReset();
241+
overlay.show.mockReset();
242+
require("../../client-src");
243+
onSocketMessage = socket.mock.calls[0][1];
244+
245+
onSocketMessage.warnings(["warn2"]);
246+
expect(overlay.show).toBeCalledTimes(1);
247+
248+
onSocketMessage.errors(["error2"]);
249+
expect(overlay.show).toBeCalledTimes(2);
250+
});
251+
});
252+
210253
test("should run onSocketMessage.error", () => {
211254
onSocketMessage.error("error!!");
212255

@@ -225,7 +268,7 @@ describe("index", () => {
225268
onSocketMessage.hot();
226269
onSocketMessage.close();
227270

228-
expect(log.log.info.mock.calls[1][0]).toMatchSnapshot();
271+
expect(log.log.info.mock.calls[0][0]).toMatchSnapshot();
229272
expect(sendMessage.mock.calls[0][0]).toMatchSnapshot();
230273
});
231274

@@ -234,7 +277,7 @@ describe("index", () => {
234277
onSocketMessage.liveReload();
235278
onSocketMessage.close();
236279

237-
expect(log.log.info.mock.calls[1][0]).toMatchSnapshot();
280+
expect(log.log.info.mock.calls[0][0]).toMatchSnapshot();
238281
expect(sendMessage.mock.calls[0][0]).toMatchSnapshot();
239282
});
240283

0 commit comments

Comments
 (0)