Skip to content

Commit 5c09e49

Browse files
authored
fix(cli): devServer.hot: false not work (#12261)
1 parent 4746bb1 commit 5c09e49

File tree

7 files changed

+58
-29
lines changed

7 files changed

+58
-29
lines changed

packages/rspack-cli/src/commands/serve.ts

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import type { Compiler, DevServer } from "@rspack/core";
1+
import type { Compiler } from "@rspack/core";
22
import type { RspackDevServer as RspackDevServerType } from "@rspack/dev-server";
33
import type { RspackCLI } from "../cli";
4+
import { DEFAULT_SERVER_HOT } from "../constants";
45
import type { RspackCommand } from "../types";
56
import {
67
type CommonOptionsForBuildAndServe,
@@ -17,14 +18,16 @@ type ServerOptions = CommonOptionsForBuildAndServe & {
1718
host?: string;
1819
};
1920

20-
function normalizeHotOption(value: unknown): ServerOptions["hot"] {
21-
if (typeof value === "boolean" || value === "only") {
22-
return value;
23-
}
21+
function normalizeHotOption(
22+
value: boolean | "true" | "false" | "only" | undefined
23+
): ServerOptions["hot"] {
2424
if (value === "false") {
2525
return false;
2626
}
27-
return true;
27+
if (value === "true") {
28+
return true;
29+
}
30+
return value;
2831
}
2932

3033
export class ServeCommand implements RspackCommand {
@@ -40,15 +43,15 @@ export class ServeCommand implements RspackCommand {
4043
.option("--port <port>", "allows to specify a port to use")
4144
.option("--host <host>", "allows to specify a hostname to use");
4245

43-
command.action(async (options: ServerOptions) => {
44-
setDefaultNodeEnv(options, "development");
45-
normalizeCommonOptions(options, "serve");
46-
options.hot = normalizeHotOption(options.hot);
46+
command.action(async (cliOptions: ServerOptions) => {
47+
setDefaultNodeEnv(cliOptions, "development");
48+
normalizeCommonOptions(cliOptions, "serve");
49+
cliOptions.hot = normalizeHotOption(cliOptions.hot);
4750

4851
// Lazy import @rspack/dev-server to avoid loading it on build mode
4952
const { RspackDevServer } = await import("@rspack/dev-server");
5053

51-
const compiler = await cli.createCompiler(options, "serve");
54+
const compiler = await cli.createCompiler(cliOptions, "serve");
5255
if (!compiler) {
5356
return;
5457
}
@@ -65,7 +68,7 @@ export class ServeCommand implements RspackCommand {
6568
const servers: RspackDevServerType[] = [];
6669

6770
/**
68-
* Webpack uses an Array of compilerForDevServer,
71+
* webpack uses an Array of compilerForDevServer,
6972
* however according to it's doc https://webpack.js.org/configuration/dev-server/#devserverhot
7073
* It should use only the first one
7174
*
@@ -79,7 +82,9 @@ export class ServeCommand implements RspackCommand {
7982
*/
8083
for (const compiler of compilers) {
8184
const devServer = (compiler.options.devServer ??= {});
82-
devServer.hot = options.hot ?? devServer.hot ?? true;
85+
86+
devServer.hot = cliOptions.hot ?? devServer.hot ?? DEFAULT_SERVER_HOT;
87+
8388
if (devServer.client !== false) {
8489
if (devServer.client === true || devServer.client == null) {
8590
devServer.client = {};
@@ -94,12 +99,13 @@ export class ServeCommand implements RspackCommand {
9499
}
95100
}
96101

97-
const result = (compilerForDevServer.options.devServer ??= {});
98-
const { setupMiddlewares } = result;
102+
const devServerOptions = (compilerForDevServer.options.devServer ??= {});
103+
const { setupMiddlewares } = devServerOptions;
99104

100105
const lazyCompileMiddleware =
101106
rspack.experiments.lazyCompilationMiddleware(compiler);
102-
result.setupMiddlewares = (middlewares, server) => {
107+
108+
devServerOptions.setupMiddlewares = (middlewares, server) => {
103109
let finalMiddlewares = middlewares;
104110
if (setupMiddlewares) {
105111
finalMiddlewares = setupMiddlewares(finalMiddlewares, server);
@@ -110,23 +116,26 @@ export class ServeCommand implements RspackCommand {
110116
/**
111117
* Enable this to tell Rspack that we need to enable React Refresh by default
112118
*/
113-
result.hot = options.hot ?? result.hot ?? true;
114-
result.host = options.host || result.host;
115-
result.port = options.port ?? result.port;
116-
if (result.client !== false) {
117-
if (result.client === true || result.client == null) {
118-
result.client = {};
119+
devServerOptions.hot =
120+
cliOptions.hot ?? devServerOptions.hot ?? DEFAULT_SERVER_HOT;
121+
devServerOptions.host = cliOptions.host || devServerOptions.host;
122+
devServerOptions.port = cliOptions.port ?? devServerOptions.port;
123+
if (devServerOptions.client !== false) {
124+
if (
125+
devServerOptions.client === true ||
126+
devServerOptions.client == null
127+
) {
128+
devServerOptions.client = {};
119129
}
120-
result.client = {
130+
devServerOptions.client = {
121131
overlay: {
122132
errors: true,
123133
warnings: false
124134
},
125-
...result.client
135+
...devServerOptions.client
126136
};
127137
}
128138

129-
const devServerOptions = result as DevServer;
130139
if (devServerOptions.port) {
131140
const portNumber = Number(devServerOptions.port);
132141

@@ -143,9 +152,7 @@ export class ServeCommand implements RspackCommand {
143152

144153
try {
145154
const server = new RspackDevServer(devServerOptions, compiler);
146-
147155
await server.start();
148-
149156
servers.push(server);
150157
} catch (error) {
151158
const logger = cli.getLogger();

packages/rspack-cli/src/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ export const DEFAULT_EXTENSIONS = [
88
".cjs",
99
".cts"
1010
] as const;
11+
12+
export const DEFAULT_SERVER_HOT = true;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module.exports = {
2+
mode: "development",
3+
devServer: {
4+
hot: false,
5+
onListening(devServer) {
6+
const { hot } = devServer.options;
7+
console.log(JSON.stringify({ hot }));
8+
}
9+
}
10+
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { normalizeStdout, runWatch } from "../../utils/test-utils";
2+
3+
test("should allow to disable HMR via `server.hot`", async () => {
4+
const { stdout } = await runWatch(__dirname, ["serve"], {
5+
killString: /localhost/
6+
});
7+
8+
expect(normalizeStdout(stdout)).toContain('{"hot":false}');
9+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
console.log("hello world");

packages/rspack-cli/tests/serve/flags/rspack.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module.exports = {
55
hot: false,
66
port: 8080,
77
host: "127.0.0.1",
8-
onListening: function (devServer) {
8+
onListening(devServer) {
99
const { hot, host, port } = devServer.options;
1010
console.log(JSON.stringify({ hot, host, port }));
1111
}

packages/rspack-cli/tests/serve/flags/serve-flags.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { normalizeStdout, runWatch } from "../../utils/test-utils";
22

33
describe("serve usage with flags", () => {
4-
it.concurrent("basic flags", async () => {
4+
test("basic flags", async () => {
55
const { stdout } = await runWatch(
66
__dirname,
77
["serve", "--host=localhost", "--port=8888", "--hot"],

0 commit comments

Comments
 (0)