Skip to content

Commit 4831f58

Browse files
authored
feat: added magicHtml option (#3717)
1 parent 3a04c60 commit 4831f58

16 files changed

+422
-7
lines changed

Diff for: README.md

+2
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ Options:
132132
--ipc [value] Listen to a unix socket.
133133
--live-reload Enables reload/refresh the page(s) when file changes are detected (enabled by default).
134134
--no-live-reload Negative 'live-reload' option.
135+
--magic-html Enables/Disables magic HTML routes (enabled by default).
136+
--no-magic-html Negative 'magic-html' option.
135137
--open [value...] Allows to configure dev server to open the browser(s) and page(s) after server had been started (set it to
136138
true to open your default browser).
137139
--no-open Negative 'open' option.

Diff for: bin/cli-flags.js

+13
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,19 @@ module.exports = {
534534
simpleType: "boolean",
535535
multiple: false,
536536
},
537+
"magic-html": {
538+
configs: [
539+
{
540+
type: "boolean",
541+
multiple: false,
542+
description: "Enables/Disables magic HTML routes (enabled by default).",
543+
path: "magicHtml",
544+
},
545+
],
546+
description: "Enables/Disables magic HTML routes (enabled by default).",
547+
simpleType: "boolean",
548+
multiple: false,
549+
},
537550
open: {
538551
configs: [
539552
{

Diff for: lib/Server.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,9 @@ class Server {
431431
options.liveReload =
432432
typeof options.liveReload !== "undefined" ? options.liveReload : true;
433433

434+
options.magicHtml =
435+
typeof options.magicHtml !== "undefined" ? options.magicHtml : true;
436+
434437
// https://github.com/webpack/webpack-dev-server/issues/1990
435438
const defaultOpenOptions = { wait: false };
436439
const getOpenItemsFromObject = ({ target, ...rest }) => {
@@ -1132,7 +1135,9 @@ class Server {
11321135
runnableFeatures.push("staticServeIndex", "staticWatch");
11331136
}
11341137

1135-
runnableFeatures.push("magicHtml");
1138+
if (this.options.magicHtml) {
1139+
runnableFeatures.push("magicHtml");
1140+
}
11361141

11371142
if (this.options.onAfterSetupMiddleware) {
11381143
runnableFeatures.push("onAfterSetupMiddleware");

Diff for: lib/options.json

+8
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,11 @@
331331
"description": "Enables reload/refresh the page(s) when file changes are detected (enabled by default).",
332332
"link": "https://webpack.js.org/configuration/dev-server/#devserverlivereload"
333333
},
334+
"MagicHTML": {
335+
"type": "boolean",
336+
"description": "Enables/Disables magic HTML routes (enabled by default).",
337+
"link": "https://webpack.js.org/configuration/dev-server/#devservermagichtml"
338+
},
334339
"OnAfterSetupMiddleware": {
335340
"instanceof": "Function",
336341
"description": "Provides the ability to execute a custom function and apply custom middleware(s) after all other middlewares.",
@@ -729,6 +734,9 @@
729734
"liveReload": {
730735
"$ref": "#/definitions/LiveReload"
731736
},
737+
"magicHtml": {
738+
"$ref": "#/definitions/MagicHTML"
739+
},
732740
"onAfterSetupMiddleware": {
733741
"$ref": "#/definitions/OnAfterSetupMiddleware"
734742
},

Diff for: test/__snapshots__/validate-options.test.js.snap.webpack4

+7
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,13 @@ exports[`options validate should throw an error on the "liveReload" option with
439439
-> Read more at https://webpack.js.org/configuration/dev-server/#devserverlivereload"
440440
`;
441441

442+
exports[`options validate should throw an error on the "magicHtml" option with 'string' value 1`] = `
443+
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
444+
- options.magicHtml should be a boolean.
445+
-> Enables/Disables magic HTML routes (enabled by default).
446+
-> Read more at https://webpack.js.org/configuration/dev-server/#devservermagichtml"
447+
`;
448+
442449
exports[`options validate should throw an error on the "onAfterSetupMiddleware" option with 'false' value 1`] = `
443450
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
444451
- options.onAfterSetupMiddleware should be an instance of function.

Diff for: test/__snapshots__/validate-options.test.js.snap.webpack5

+7
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,13 @@ exports[`options validate should throw an error on the "liveReload" option with
439439
-> Read more at https://webpack.js.org/configuration/dev-server/#devserverlivereload"
440440
`;
441441

442+
exports[`options validate should throw an error on the "magicHtml" option with 'string' value 1`] = `
443+
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
444+
- options.magicHtml should be a boolean.
445+
-> Enables/Disables magic HTML routes (enabled by default).
446+
-> Read more at https://webpack.js.org/configuration/dev-server/#devservermagichtml"
447+
`;
448+
442449
exports[`options validate should throw an error on the "onAfterSetupMiddleware" option with 'false' value 1`] = `
443450
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
444451
- options.onAfterSetupMiddleware should be an instance of function.

Diff for: test/cli/__snapshots__/basic.test.js.snap.webpack4

+2
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ Options:
9999
--ipc [value] Listen to a unix socket.
100100
--live-reload Enables reload/refresh the page(s) when file changes are detected (enabled by default).
101101
--no-live-reload Disables reload/refresh the page(s) when file changes are detected (enabled by default)
102+
--magic-html Enables/Disables magic HTML routes (enabled by default).
103+
--no-magic-html Negative 'magic-html' option.
102104
--open [value...] Allows to configure dev server to open the browser(s) and page(s) after server had been started (set it to true to open your default browser).
103105
--no-open Does not open the default browser.
104106
--open-target <value...> Opens specified page in browser.

Diff for: test/cli/__snapshots__/basic.test.js.snap.webpack5

+2
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ Options:
9898
--ipc [value] Listen to a unix socket.
9999
--live-reload Enables reload/refresh the page(s) when file changes are detected (enabled by default).
100100
--no-live-reload Negative 'live-reload' option.
101+
--magic-html Enables/Disables magic HTML routes (enabled by default).
102+
--no-magic-html Negative 'magic-html' option.
101103
--open [value...] Allows to configure dev server to open the browser(s) and page(s) after server had been started (set it to true to open your default browser).
102104
--no-open Negative 'open' option.
103105
--open-target <value...> Opens specified page in browser.

Diff for: test/cli/magicHtml-option.test.js

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"use strict";
2+
3+
const { testBin } = require("../helpers/test-bin");
4+
const port = require("../ports-map")["cli-magic-html"];
5+
6+
describe('"liveReload" CLI option', () => {
7+
it('should work using "--magic-html"', async () => {
8+
const { exitCode } = await testBin(["--port", port, "--magic-html"]);
9+
10+
expect(exitCode).toEqual(0);
11+
});
12+
13+
it('should work using "--no-magic-html"', async () => {
14+
const { exitCode } = await testBin(["--port", port, "--no-magic-html"]);
15+
16+
expect(exitCode).toEqual(0);
17+
});
18+
});
+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`magicHtml option disabled should not handle GET request to magic async html: console messages 1`] = `
4+
Array [
5+
"Failed to load resource: the server responded with a status of 404 (Not Found)",
6+
]
7+
`;
8+
9+
exports[`magicHtml option disabled should not handle GET request to magic async html: response headers content-type 1`] = `"text/html; charset=utf-8"`;
10+
11+
exports[`magicHtml option disabled should not handle GET request to magic async html: response status 1`] = `404`;
12+
13+
exports[`magicHtml option disabled should not handle HEAD request to magic async html: console messages 1`] = `
14+
Array [
15+
"Failed to load resource: the server responded with a status of 404 (Not Found)",
16+
]
17+
`;
18+
19+
exports[`magicHtml option disabled should not handle HEAD request to magic async html: response headers content-type 1`] = `"text/html; charset=utf-8"`;
20+
21+
exports[`magicHtml option disabled should not handle HEAD request to magic async html: response status 1`] = `404`;
22+
23+
exports[`magicHtml option enabled should handle GET request to magic async html: console messages 1`] = `
24+
Array [
25+
"[HMR] Waiting for update signal from WDS...",
26+
"Hey.",
27+
"[webpack-dev-server] Hot Module Replacement enabled.",
28+
"[webpack-dev-server] Live Reloading enabled.",
29+
]
30+
`;
31+
32+
exports[`magicHtml option enabled should handle GET request to magic async html: response headers content-type 1`] = `"text/html; charset=utf-8"`;
33+
34+
exports[`magicHtml option enabled should handle GET request to magic async html: response status 1`] = `200`;
35+
36+
exports[`magicHtml option enabled should handle HEAD request to magic async html: console messages 1`] = `Array []`;
37+
38+
exports[`magicHtml option enabled should handle HEAD request to magic async html: response headers content-type 1`] = `"text/html; charset=utf-8"`;
39+
40+
exports[`magicHtml option enabled should handle HEAD request to magic async html: response status 1`] = `200`;
+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`magicHtml option disabled should not handle GET request to magic async html: console messages 1`] = `
4+
Array [
5+
"Failed to load resource: the server responded with a status of 404 (Not Found)",
6+
]
7+
`;
8+
9+
exports[`magicHtml option disabled should not handle GET request to magic async html: response headers content-type 1`] = `"text/html; charset=utf-8"`;
10+
11+
exports[`magicHtml option disabled should not handle GET request to magic async html: response status 1`] = `404`;
12+
13+
exports[`magicHtml option disabled should not handle HEAD request to magic async html: console messages 1`] = `
14+
Array [
15+
"Failed to load resource: the server responded with a status of 404 (Not Found)",
16+
]
17+
`;
18+
19+
exports[`magicHtml option disabled should not handle HEAD request to magic async html: response headers content-type 1`] = `"text/html; charset=utf-8"`;
20+
21+
exports[`magicHtml option disabled should not handle HEAD request to magic async html: response status 1`] = `404`;
22+
23+
exports[`magicHtml option enabled should handle GET request to magic async html: console messages 1`] = `
24+
Array [
25+
"[HMR] Waiting for update signal from WDS...",
26+
"Hey.",
27+
"[webpack-dev-server] Hot Module Replacement enabled.",
28+
"[webpack-dev-server] Live Reloading enabled.",
29+
]
30+
`;
31+
32+
exports[`magicHtml option enabled should handle GET request to magic async html: response headers content-type 1`] = `"text/html; charset=utf-8"`;
33+
34+
exports[`magicHtml option enabled should handle GET request to magic async html: response status 1`] = `200`;
35+
36+
exports[`magicHtml option enabled should handle HEAD request to magic async html: console messages 1`] = `Array []`;
37+
38+
exports[`magicHtml option enabled should handle HEAD request to magic async html: response headers content-type 1`] = `"text/html; charset=utf-8"`;
39+
40+
exports[`magicHtml option enabled should handle HEAD request to magic async html: response status 1`] = `200`;

Diff for: test/e2e/magic-html.test.js

+167
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
"use strict";
2+
3+
const webpack = require("webpack");
4+
const Server = require("../../lib/Server");
5+
const config = require("../fixtures/client-config/webpack.config");
6+
const runBrowser = require("../helpers/run-browser");
7+
const port = require("../ports-map")["magic-html-option"];
8+
9+
describe("magicHtml option", () => {
10+
describe("enabled", () => {
11+
let compiler;
12+
let server;
13+
let page;
14+
let browser;
15+
let pageErrors;
16+
let consoleMessages;
17+
18+
beforeEach(async () => {
19+
compiler = webpack(config);
20+
server = new Server({ port, magicHtml: true }, compiler);
21+
22+
await server.start();
23+
24+
({ page, browser } = await runBrowser());
25+
26+
pageErrors = [];
27+
consoleMessages = [];
28+
});
29+
30+
afterEach(async () => {
31+
await browser.close();
32+
await server.stop();
33+
});
34+
35+
it("should handle GET request to magic async html", async () => {
36+
page
37+
.on("console", (message) => {
38+
consoleMessages.push(message);
39+
})
40+
.on("pageerror", (error) => {
41+
pageErrors.push(error);
42+
});
43+
44+
const response = await page.goto(`http://127.0.0.1:${port}/main`, {
45+
waitUntil: "networkidle0",
46+
});
47+
48+
expect(response.headers()["content-type"]).toMatchSnapshot(
49+
"response headers content-type"
50+
);
51+
52+
expect(response.status()).toMatchSnapshot("response status");
53+
54+
expect(consoleMessages.map((message) => message.text())).toMatchSnapshot(
55+
"console messages"
56+
);
57+
});
58+
59+
it("should handle HEAD request to magic async html", async () => {
60+
await page.setRequestInterception(true);
61+
62+
page
63+
.on("console", (message) => {
64+
consoleMessages.push(message);
65+
})
66+
.on("pageerror", (error) => {
67+
pageErrors.push(error);
68+
})
69+
.on("request", (interceptedRequest) => {
70+
interceptedRequest.continue({ method: "HEAD" });
71+
});
72+
73+
const response = await page.goto(`http://127.0.0.1:${port}/main`, {
74+
waitUntil: "networkidle0",
75+
});
76+
77+
expect(response.headers()["content-type"]).toMatchSnapshot(
78+
"response headers content-type"
79+
);
80+
81+
expect(response.status()).toMatchSnapshot("response status");
82+
83+
expect(consoleMessages.map((message) => message.text())).toMatchSnapshot(
84+
"console messages"
85+
);
86+
});
87+
});
88+
89+
describe("disabled", () => {
90+
let compiler;
91+
let server;
92+
let page;
93+
let browser;
94+
let pageErrors;
95+
let consoleMessages;
96+
97+
beforeEach(async () => {
98+
compiler = webpack(config);
99+
server = new Server({ port, magicHtml: false }, compiler);
100+
101+
await server.start();
102+
103+
({ page, browser } = await runBrowser());
104+
105+
pageErrors = [];
106+
consoleMessages = [];
107+
});
108+
109+
afterEach(async () => {
110+
await browser.close();
111+
await server.stop();
112+
});
113+
114+
it("should not handle GET request to magic async html", async () => {
115+
page
116+
.on("console", (message) => {
117+
consoleMessages.push(message);
118+
})
119+
.on("pageerror", (error) => {
120+
pageErrors.push(error);
121+
});
122+
123+
const response = await page.goto(`http://127.0.0.1:${port}/main`, {
124+
waitUntil: "networkidle0",
125+
});
126+
127+
expect(response.headers()["content-type"]).toMatchSnapshot(
128+
"response headers content-type"
129+
);
130+
131+
expect(response.status()).toMatchSnapshot("response status");
132+
133+
expect(consoleMessages.map((message) => message.text())).toMatchSnapshot(
134+
"console messages"
135+
);
136+
});
137+
138+
it("should not handle HEAD request to magic async html", async () => {
139+
await page.setRequestInterception(true);
140+
141+
page
142+
.on("console", (message) => {
143+
consoleMessages.push(message);
144+
})
145+
.on("pageerror", (error) => {
146+
pageErrors.push(error);
147+
})
148+
.on("request", (interceptedRequest) => {
149+
interceptedRequest.continue({ method: "HEAD" });
150+
});
151+
152+
const response = await page.goto(`http://127.0.0.1:${port}/main`, {
153+
waitUntil: "networkidle0",
154+
});
155+
156+
expect(response.headers()["content-type"]).toMatchSnapshot(
157+
"response headers content-type"
158+
);
159+
160+
expect(response.status()).toMatchSnapshot("response status");
161+
162+
expect(consoleMessages.map((message) => message.text())).toMatchSnapshot(
163+
"console messages"
164+
);
165+
});
166+
});
167+
});

0 commit comments

Comments
 (0)