Skip to content

Commit 83de0c8

Browse files
refactor: support devServer: false (#4045)
1 parent d442886 commit 83de0c8

14 files changed

+277
-285
lines changed

package.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@
7575
"execa": "^5.0.0",
7676
"get-port": "^5.1.1",
7777
"husky": "^9.1.4",
78-
"internal-ip": "^6.2.0",
7978
"jest": "^29.4.1",
8079
"jest-watch-typeahead": "^2.2.2",
8180
"lerna": "^8.1.8",
@@ -95,6 +94,6 @@
9594
"typescript": "^5.0.4",
9695
"webpack": "^5.94.0",
9796
"webpack-bundle-analyzer": "^4.5.0",
98-
"webpack-dev-server": "^5.0.2"
97+
"webpack-dev-server": "^5.1.0"
9998
}
10099
}

packages/serve/src/index.ts

+16
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class ServeCommand {
6666

6767
// eslint-disable-next-line @typescript-eslint/no-explicit-any
6868
const processors: Array<(opts: Record<string, any>) => void> = [];
69+
6970
for (const optionName in options) {
7071
const kebabedOption = cli.toKebabCase(optionName);
7172
const isBuiltInOption = builtInOptions.find(
@@ -89,6 +90,7 @@ class ServeCommand {
8990
devServerCLIOptions[optionName] = options[optionName];
9091
}
9192
}
93+
9294
for (const processor of processors) {
9395
processor(devServerCLIOptions);
9496
}
@@ -103,11 +105,13 @@ class ServeCommand {
103105
};
104106

105107
webpackCLIOptions.isWatchingLikeCommand = true;
108+
106109
const compiler = await cli.createCompiler(webpackCLIOptions);
107110

108111
if (!compiler) {
109112
return;
110113
}
114+
111115
const servers: (typeof DevServer)[] = [];
112116

113117
if (cli.needWatchStdin(compiler)) {
@@ -144,6 +148,12 @@ class ServeCommand {
144148
const usedPorts: number[] = [];
145149

146150
for (const compilerForDevServer of compilersForDevServer) {
151+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
152+
// @ts-ignore
153+
if (compilerForDevServer.options.devServer === false) {
154+
continue;
155+
}
156+
147157
// eslint-disable-next-line @typescript-eslint/no-explicit-any
148158
const args = devServerFlags.reduce((accumulator: Record<string, any>, flag: any) => {
149159
accumulator[flag.name] = flag;
@@ -203,6 +213,7 @@ class ServeCommand {
203213
}
204214

205215
const devServerOptions: WebpackDevServerOptions = result as WebpackDevServerOptions;
216+
206217
if (devServerOptions.port) {
207218
const portNumber = Number(devServerOptions.port);
208219

@@ -231,6 +242,11 @@ class ServeCommand {
231242
process.exit(2);
232243
}
233244
}
245+
246+
if (servers.length === 0) {
247+
cli.logger.error("No dev server configurations to run");
248+
process.exit(2);
249+
}
234250
},
235251
);
236252
}

packages/webpack-cli/src/webpack-cli.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -2391,14 +2391,12 @@ class WebpackCLI implements IWebpackCLI {
23912391
} else if (typeof options.nodeEnv === "string") {
23922392
process.env.NODE_ENV = options.nodeEnv;
23932393
}
2394+
23942395
let config = await this.loadConfig(options);
23952396
config = await this.buildConfig(config, options);
2396-
const { devServer } = config.options as boolean | WebpackDevServerOptions["options"];
2397-
const devServerIsFalse = devServer !== undefined && devServer === false;
2398-
if (devServerIsFalse && options.argv && options.argv.env && options.argv.env.WEBPACK_SERVE) {
2399-
process.exit(0);
2400-
}
2397+
24012398
let compiler: WebpackCompiler;
2399+
24022400
try {
24032401
compiler = this.webpack(
24042402
config.options as WebpackConfiguration,

test/serve/basic/__snapshots__/serve-basic.test.js.snap.devServer4.webpack5

+66-58
Large diffs are not rendered by default.

test/serve/basic/__snapshots__/serve-basic.test.js.snap.devServer5.webpack5

+95-87
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const WebpackCLITestPlugin = require("../../utils/webpack-cli-test-plugin");
2+
3+
module.exports = [
4+
{
5+
name: "app",
6+
dependencies: ["worker"],
7+
mode: "development",
8+
devtool: false,
9+
target: "web",
10+
entry: "./src/index.js",
11+
plugins: [new WebpackCLITestPlugin(["mode"], false, "hooks.compilation.taps")],
12+
},
13+
{
14+
name: "worker",
15+
mode: "development",
16+
devtool: false,
17+
target: "webworker",
18+
entry: "./src/worker.js",
19+
devServer: false,
20+
},
21+
];

test/serve/basic/serve-basic.test.js

+15-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,21 @@ describe("basic serve usage", () => {
123123
normalStdKillOptions,
124124
);
125125
expect(stdout).toBeFalsy();
126-
expect(stderr).toBeFalsy();
126+
expect(stderr).toContain("No dev server configurations to run");
127+
});
128+
129+
it("should not start dev server when supplied false #1", async () => {
130+
const { stderr, stdout } = await runWatch(
131+
__dirname,
132+
["serve", "--config", "dev-server-false.multi.config.js"],
133+
normalStdKillOptions,
134+
);
135+
136+
expect(normalizeStderr(stderr)).toMatchSnapshot("stderr");
137+
expect(stdout).toContain("app:");
138+
expect(stdout).toContain("worker:");
139+
expect(stdout).toContain("HotModuleReplacementPlugin");
140+
expect(stdout).toContain("compiled successfully");
127141
});
128142

129143
it('should work with the "--stats" option', async () => {

test/serve/basic/src/worker.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
console.log("Worker");

test/serve/serve-variable/__snapshots__/serve-variable.test.js.snap.devServer4.webpack5

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
exports[`serve variable compiles without flags and export variable 1`] = `
44
"<i> [webpack-dev-server] Project is running at:
55
<i> [webpack-dev-server] Loopback: http://localhost:<port>/
6-
<i> [webpack-dev-server] On Your Network (IPv4): http://<network-ip-v4>:<port>/
7-
<i> [webpack-dev-server] On Your Network (IPv6): http://[<network-ip-v6>]:<port>/
6+
<i> [webpack-dev-server] On Your Network (IPv4): http://x.x.x.x:<port>/
7+
<i> [webpack-dev-server] On Your Network (IPv6): http://[x:x:x:x:x:x:x:x]:<port>/
88
<i> [webpack-dev-server] Content not from webpack is served from '<cwd>/test/serve/serve-variable/public' directory"
99
`;

test/serve/serve-variable/__snapshots__/serve-variable.test.js.snap.devServer5.webpack5

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
exports[`serve variable compiles without flags and export variable 1`] = `
44
"<i> [webpack-dev-server] Project is running at:
5-
<i> [webpack-dev-server] Loopback: http://localhost:<port>/
6-
<i> [webpack-dev-server] On Your Network (IPv4): http://<network-ip-v4>:<port>/
7-
<i> [webpack-dev-server] On Your Network (IPv6): http://[<network-ip-v6>]:<port>/
5+
<i> [webpack-dev-server] Loopback: http://localhost:<port>/, http://[::1]:<port>/
6+
<i> [webpack-dev-server] On Your Network (IPv4): http://x.x.x.x:<port>/
7+
<i> [webpack-dev-server] On Your Network (IPv6): http://[x:x:x:x:x:x:x:x]:<port>/
88
<i> [webpack-dev-server] Content not from webpack is served from '<cwd>/test/serve/serve-variable/public' directory"
99
`;

test/serve/with-custom-port/__snapshots__/serve-custom-config.test.js.snap.devServer4.webpack5

+8-8
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,31 @@
33
exports[`serve with devServer in config Passing hot flag works alongside other server config: stderr 1`] = `
44
"<i> [webpack-dev-server] Project is running at:
55
<i> [webpack-dev-server] Loopback: http://localhost:<port>/
6-
<i> [webpack-dev-server] On Your Network (IPv4): http://<network-ip-v4>:<port>/
7-
<i> [webpack-dev-server] On Your Network (IPv6): http://[<network-ip-v6>]:<port>/
6+
<i> [webpack-dev-server] On Your Network (IPv4): http://x.x.x.x:<port>/
7+
<i> [webpack-dev-server] On Your Network (IPv6): http://[x:x:x:x:x:x:x:x]:<port>/
88
<i> [webpack-dev-server] Content not from webpack is served from '<cwd>/test/serve/with-custom-port/public' directory"
99
`;
1010

1111
exports[`serve with devServer in config Port flag should override the config port: stderr 1`] = `
1212
"<i> [webpack-dev-server] Project is running at:
1313
<i> [webpack-dev-server] Loopback: http://localhost:<port>/
14-
<i> [webpack-dev-server] On Your Network (IPv4): http://<network-ip-v4>:<port>/
15-
<i> [webpack-dev-server] On Your Network (IPv6): http://[<network-ip-v6>]:<port>/
14+
<i> [webpack-dev-server] On Your Network (IPv4): http://x.x.x.x:<port>/
15+
<i> [webpack-dev-server] On Your Network (IPv6): http://[x:x:x:x:x:x:x:x]:<port>/
1616
<i> [webpack-dev-server] Content not from webpack is served from '<cwd>/test/serve/with-custom-port/public' directory"
1717
`;
1818

1919
exports[`serve with devServer in config Should pick up the host and port from config: stderr 1`] = `
2020
"<i> [webpack-dev-server] Project is running at:
2121
<i> [webpack-dev-server] Loopback: http://localhost:<port>/
22-
<i> [webpack-dev-server] On Your Network (IPv4): http://<network-ip-v4>:<port>/
23-
<i> [webpack-dev-server] On Your Network (IPv6): http://[<network-ip-v6>]:<port>/
22+
<i> [webpack-dev-server] On Your Network (IPv4): http://x.x.x.x:<port>/
23+
<i> [webpack-dev-server] On Your Network (IPv6): http://[x:x:x:x:x:x:x:x]:<port>/
2424
<i> [webpack-dev-server] Content not from webpack is served from '<cwd>/test/serve/with-custom-port/public' directory"
2525
`;
2626

2727
exports[`serve with devServer in config works fine when no-hot flag is passed alongside other server config: stderr 1`] = `
2828
"<i> [webpack-dev-server] Project is running at:
2929
<i> [webpack-dev-server] Loopback: http://localhost:<port>/
30-
<i> [webpack-dev-server] On Your Network (IPv4): http://<network-ip-v4>:<port>/
31-
<i> [webpack-dev-server] On Your Network (IPv6): http://[<network-ip-v6>]:<port>/
30+
<i> [webpack-dev-server] On Your Network (IPv4): http://x.x.x.x:<port>/
31+
<i> [webpack-dev-server] On Your Network (IPv6): http://[x:x:x:x:x:x:x:x]:<port>/
3232
<i> [webpack-dev-server] Content not from webpack is served from '<cwd>/test/serve/with-custom-port/public' directory"
3333
`;

test/serve/with-custom-port/__snapshots__/serve-custom-config.test.js.snap.devServer5.webpack5

+12-12
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,32 @@
22

33
exports[`serve with devServer in config Passing hot flag works alongside other server config: stderr 1`] = `
44
"<i> [webpack-dev-server] Project is running at:
5-
<i> [webpack-dev-server] Loopback: http://localhost:<port>/
6-
<i> [webpack-dev-server] On Your Network (IPv4): http://<network-ip-v4>:<port>/
7-
<i> [webpack-dev-server] On Your Network (IPv6): http://[<network-ip-v6>]:<port>/
5+
<i> [webpack-dev-server] Loopback: http://localhost:<port>/, http://[::1]:<port>/
6+
<i> [webpack-dev-server] On Your Network (IPv4): http://x.x.x.x:<port>/
7+
<i> [webpack-dev-server] On Your Network (IPv6): http://[x:x:x:x:x:x:x:x]:<port>/
88
<i> [webpack-dev-server] Content not from webpack is served from '<cwd>/test/serve/with-custom-port/public' directory"
99
`;
1010

1111
exports[`serve with devServer in config Port flag should override the config port: stderr 1`] = `
1212
"<i> [webpack-dev-server] Project is running at:
13-
<i> [webpack-dev-server] Loopback: http://localhost:<port>/
14-
<i> [webpack-dev-server] On Your Network (IPv4): http://<network-ip-v4>:<port>/
15-
<i> [webpack-dev-server] On Your Network (IPv6): http://[<network-ip-v6>]:<port>/
13+
<i> [webpack-dev-server] Loopback: http://localhost:<port>/, http://[::1]:<port>/
14+
<i> [webpack-dev-server] On Your Network (IPv4): http://x.x.x.x:<port>/
15+
<i> [webpack-dev-server] On Your Network (IPv6): http://[x:x:x:x:x:x:x:x]:<port>/
1616
<i> [webpack-dev-server] Content not from webpack is served from '<cwd>/test/serve/with-custom-port/public' directory"
1717
`;
1818

1919
exports[`serve with devServer in config Should pick up the host and port from config: stderr 1`] = `
2020
"<i> [webpack-dev-server] Project is running at:
21-
<i> [webpack-dev-server] Loopback: http://localhost:<port>/
22-
<i> [webpack-dev-server] On Your Network (IPv4): http://<network-ip-v4>:<port>/
23-
<i> [webpack-dev-server] On Your Network (IPv6): http://[<network-ip-v6>]:<port>/
21+
<i> [webpack-dev-server] Loopback: http://localhost:<port>/, http://[::1]:<port>/
22+
<i> [webpack-dev-server] On Your Network (IPv4): http://x.x.x.x:<port>/
23+
<i> [webpack-dev-server] On Your Network (IPv6): http://[x:x:x:x:x:x:x:x]:<port>/
2424
<i> [webpack-dev-server] Content not from webpack is served from '<cwd>/test/serve/with-custom-port/public' directory"
2525
`;
2626

2727
exports[`serve with devServer in config works fine when no-hot flag is passed alongside other server config: stderr 1`] = `
2828
"<i> [webpack-dev-server] Project is running at:
29-
<i> [webpack-dev-server] Loopback: http://localhost:<port>/
30-
<i> [webpack-dev-server] On Your Network (IPv4): http://<network-ip-v4>:<port>/
31-
<i> [webpack-dev-server] On Your Network (IPv6): http://[<network-ip-v6>]:<port>/
29+
<i> [webpack-dev-server] Loopback: http://localhost:<port>/, http://[::1]:<port>/
30+
<i> [webpack-dev-server] On Your Network (IPv4): http://x.x.x.x:<port>/
31+
<i> [webpack-dev-server] On Your Network (IPv6): http://[x:x:x:x:x:x:x:x]:<port>/
3232
<i> [webpack-dev-server] Content not from webpack is served from '<cwd>/test/serve/with-custom-port/public' directory"
3333
`;

test/utils/test-utils.js

+6-14
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ const stripAnsi = require("strip-ansi");
55
const path = require("path");
66
const fs = require("fs");
77
const execa = require("execa");
8-
const internalIp = require("internal-ip");
98
const { exec } = require("child_process");
109
const { node: execaNode } = execa;
1110
const { Writable } = require("readable-stream");
@@ -272,6 +271,9 @@ const normalizeStdout = (stdout) => {
272271
return normalizedStdout;
273272
};
274273

274+
const IPV4 = /(25[0-5]|2[0-4][0-9]|1?[0-9][0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})){3}/g;
275+
const IPV6 = /([0-9a-f]){1,4}(:([0-9a-f]){1,4}){7}/gi;
276+
275277
const normalizeStderr = (stderr) => {
276278
if (typeof stderr !== "string") {
277279
return stderr;
@@ -284,18 +286,8 @@ const normalizeStderr = (stderr) => {
284286
let normalizedStderr = stripAnsi(stderr);
285287
normalizedStderr = normalizeCwd(normalizedStderr);
286288

287-
const networkIPv4 = internalIp.v4.sync();
288-
289-
if (networkIPv4) {
290-
normalizedStderr = normalizedStderr.replace(new RegExp(networkIPv4, "g"), "<network-ip-v4>");
291-
}
292-
293-
const networkIPv6 = internalIp.v6.sync();
294-
295-
if (networkIPv6) {
296-
normalizedStderr = normalizedStderr.replace(new RegExp(networkIPv6, "g"), "<network-ip-v6>");
297-
}
298-
289+
normalizedStderr = normalizedStderr.replace(IPV4, "x.x.x.x");
290+
normalizedStderr = normalizedStderr.replace(IPV6, "[x:x:x:x:x:x:x:x]");
299291
normalizedStderr = normalizedStderr.replace(/:[0-9]+\//g, ":<port>/");
300292

301293
if (!/On Your Network \(IPv6\)/.test(stderr)) {
@@ -310,7 +302,7 @@ const normalizeStderr = (stderr) => {
310302
normalizedStderr.splice(
311303
ipv4MessageIndex + 1,
312304
0,
313-
"<i> [webpack-dev-server] On Your Network (IPv6): http://[<network-ip-v6>]:<port>/",
305+
"<i> [webpack-dev-server] On Your Network (IPv6): http://[x:x:x:x:x:x:x:x]:<port>/",
314306
);
315307
}
316308

0 commit comments

Comments
 (0)