Skip to content

Commit 3fc8f77

Browse files
committed
refactor(hot): drop the module map from the SSE payload (#2349)
webpack-dev-server does not send module names over the wire: the HMR runtime logs module ids on apply. Align the SSE payload with that (name, action, time, hash, errors, warnings) instead of serializing a module id → name map that was only used for log cosmetics and was empty with the default stats options anyway. Ref webpack/webpack-hot-middleware#452 Ref webpack/webpack-hot-middleware#306
1 parent 50c4980 commit 3fc8f77

8 files changed

Lines changed: 35 additions & 57 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ Heartbeat interval (in milliseconds) used to keep the SSE connection alive when
349349
Type: `Boolean | Object`
350350
Default: `undefined`
351351

352-
Webpack stats options used when serializing compilation results for the SSE payload. Forwarded to `stats.toJson(...)`. By default only the minimal stats needed by the client are requested (`hash`, `timings`, `errors`, `warnings`) to avoid slowing down rebuilds. Pass `statsOptions: { modules: true }` if you want the module id → name map used for nicer client logging.
352+
Webpack stats options used when serializing compilation results for the SSE payload. Forwarded to `stats.toJson(...)`. By default only the minimal stats needed by the client are requested (`hash`, `timings`, `errors`, `warnings`) to avoid slowing down rebuilds.
353353

354354
## Hot Module Replacement client
355355

client-src/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ export function setOptionsAndConnect(overrides) {
182182
// eslint-disable-next-line jsdoc/reject-any-type
183183
/** @typedef {any} EXPECTED_ANY */
184184

185-
/** @typedef {{ name?: string, errors: string[], warnings: string[], hash: string, time?: number, modules?: Record<string, string>, action?: string }} HMRPayload */
185+
/** @typedef {{ name?: string, errors: string[], warnings: string[], hash: string, time?: number, action?: string }} HMRPayload */
186186

187187
/**
188188
* @returns {{
@@ -294,7 +294,7 @@ function processMessage(obj) {
294294
reporter.success();
295295
}
296296
if (shouldApply) {
297-
applyUpdate(obj.hash, obj.modules, options);
297+
applyUpdate(obj.hash, options);
298298
}
299299
break;
300300
}

client-src/process-update.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,9 @@ function upToDate(hash) {
4949

5050
/**
5151
* @param {string} hash latest hash from the SSE payload
52-
* @param {Record<string, string> | undefined} moduleMap module id → name map
5352
* @param {{ reload?: boolean }} options client options
5453
*/
55-
export default function applyUpdate(hash, moduleMap, options) {
54+
export default function applyUpdate(hash, options) {
5655
const { reload } = options;
5756

5857
/**
@@ -96,7 +95,7 @@ export default function applyUpdate(hash, moduleMap, options) {
9695
`See ${HMR_DOCS_URL} for more details.`,
9796
);
9897
for (const moduleId of unacceptedModules) {
99-
log.warn(` - ${(moduleMap && moduleMap[moduleId]) || moduleId}`);
98+
log.warn(` - ${moduleId}`);
10099
}
101100
performReload();
102101
return;
@@ -107,7 +106,7 @@ export default function applyUpdate(hash, moduleMap, options) {
107106
} else {
108107
log.info("Updated modules:");
109108
for (const moduleId of renewedModules) {
110-
log.info(` - ${(moduleMap && moduleMap[moduleId]) || moduleId}`);
109+
log.info(` - ${moduleId}`);
111110
}
112111
}
113112

src/hot.js

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
/** @typedef {import("webpack").MultiStats} MultiStats */
66
/** @typedef {import("webpack").StatsCompilation} StatsCompilation */
77
/** @typedef {import("webpack").StatsError} StatsError */
8-
/** @typedef {import("webpack").StatsModule} StatsModule */
98
/** @typedef {import("./index.js").IncomingMessage} IncomingMessage */
109
/** @typedef {import("./index.js").ServerResponse} ServerResponse */
1110

@@ -26,7 +25,6 @@
2625
* @property {string=} hash hash
2726
* @property {string[]=} warnings warnings
2827
* @property {string[]=} errors errors
29-
* @property {Record<string, string>=} modules modules
3028
*/
3129

3230
/**
@@ -191,23 +189,6 @@ function extractBundles(stats) {
191189
return [stats];
192190
}
193191

194-
/**
195-
* @param {StatsModule[]} modules modules
196-
* @returns {Record<string, string>} module id to name map
197-
*/
198-
function buildModuleMap(modules) {
199-
/** @type {Record<string, string>} */
200-
const map = {};
201-
202-
for (const item of modules) {
203-
map[/** @type {string | number} */ (item.id)] = /** @type {string} */ (
204-
item.name
205-
);
206-
}
207-
208-
return map;
209-
}
210-
211192
/**
212193
* @param {string} action action
213194
* @param {Stats | MultiStats} statsResult stats result
@@ -251,7 +232,6 @@ function publishStats(action, statsResult, eventStream, statsOptions) {
251232
hash: stats.hash,
252233
warnings: formatErrors(stats.warnings || []),
253234
errors: formatErrors(stats.errors || []),
254-
modules: buildModuleMap(stats.modules || []),
255235
});
256236
}
257237
}
@@ -332,7 +312,6 @@ function createHot(compiler, userOptions) {
332312
module.exports = createHot;
333313
module.exports.HOT_DEFAULT_HEARTBEAT = HOT_DEFAULT_HEARTBEAT;
334314
module.exports.HOT_DEFAULT_PATH = HOT_DEFAULT_PATH;
335-
module.exports.buildModuleMap = buildModuleMap;
336315
module.exports.createEventStream = createEventStream;
337316
module.exports.createHot = createHot;
338317
module.exports.formatErrors = formatErrors;

test/client.test.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,6 @@ describe("client", () => {
141141
);
142142
expect(processUpdate).toHaveBeenCalledWith(
143143
"1234567890abcdef",
144-
expect.anything(),
145144
expect.objectContaining({ reload: true }),
146145
);
147146
});
@@ -530,7 +529,6 @@ describe("client", () => {
530529
);
531530
expect(processUpdate).toHaveBeenCalledWith(
532531
"1234567890abcdef",
533-
expect.anything(),
534532
expect.objectContaining({ reload: false }),
535533
);
536534
});

test/helpers/sse.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import http from "node:http";
88
* @property {number=} time build time in ms
99
* @property {string[]=} errors errors
1010
* @property {string[]=} warnings warnings
11-
* @property {Record<string, string>=} modules module id → name map
1211
*/
1312

1413
/**

test/hot.test.js

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import createHot, {
2-
buildModuleMap,
32
createEventStream,
43
formatErrors,
54
pathMatch,
@@ -138,17 +137,6 @@ describe("hot middleware (unit)", () => {
138137
});
139138
});
140139

141-
describe("buildModuleMap", () => {
142-
it("maps id to name", () => {
143-
expect(
144-
buildModuleMap([
145-
{ id: 1, name: "./a.js" },
146-
{ id: 2, name: "./b.js" },
147-
]),
148-
).toEqual({ 1: "./a.js", 2: "./b.js" });
149-
});
150-
});
151-
152140
describe("createEventStream", () => {
153141
beforeEach(() => {
154142
jest.useFakeTimers();
@@ -370,6 +358,35 @@ describe("createHot", () => {
370358
hot.close();
371359
});
372360

361+
it("forwards custom statsOptions to stats.toJson", () => {
362+
const compiler = makeFakeCompiler();
363+
const hot = createHot(compiler, {
364+
statsOptions: { modules: true, ids: true },
365+
});
366+
attachClient({ handler: hot.handle });
367+
368+
/** @type {EXPECTED_OBJECT} */
369+
let receivedOptions;
370+
371+
compiler.emitDone({
372+
toJson(statsOptions) {
373+
receivedOptions = statsOptions;
374+
return {
375+
time: 1,
376+
hash: "h",
377+
warnings: [],
378+
errors: [],
379+
modules: [],
380+
};
381+
},
382+
compilation: undefined,
383+
});
384+
385+
expect(receivedOptions).toMatchObject({ modules: true, ids: true });
386+
387+
hot.close();
388+
});
389+
373390
it("stops publishing after close() even if the compiler still emits", () => {
374391
const compiler = makeFakeCompiler();
375392
const hot = createHot(compiler, {});

types/hot.d.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ declare namespace createHot {
1919
export {
2020
HOT_DEFAULT_HEARTBEAT,
2121
HOT_DEFAULT_PATH,
22-
buildModuleMap,
2322
createEventStream,
2423
createHot,
2524
formatErrors,
@@ -33,7 +32,6 @@ declare namespace createHot {
3332
MultiStats,
3433
StatsCompilation,
3534
StatsError,
36-
StatsModule,
3735
IncomingMessage,
3836
ServerResponse,
3937
StatsOptions,
@@ -50,7 +48,6 @@ declare const HOT_DEFAULT_HEARTBEAT: number;
5048
/** @typedef {import("webpack").MultiStats} MultiStats */
5149
/** @typedef {import("webpack").StatsCompilation} StatsCompilation */
5250
/** @typedef {import("webpack").StatsError} StatsError */
53-
/** @typedef {import("webpack").StatsModule} StatsModule */
5451
/** @typedef {import("./index.js").IncomingMessage} IncomingMessage */
5552
/** @typedef {import("./index.js").ServerResponse} ServerResponse */
5653
/** @typedef {NonNullable<import("webpack").Configuration["stats"]>} StatsOptions */
@@ -68,7 +65,6 @@ declare const HOT_DEFAULT_HEARTBEAT: number;
6865
* @property {string=} hash hash
6966
* @property {string[]=} warnings warnings
7067
* @property {string[]=} errors errors
71-
* @property {Record<string, string>=} modules modules
7268
*/
7369
/**
7470
* @typedef {object} EventStream
@@ -77,11 +73,6 @@ declare const HOT_DEFAULT_HEARTBEAT: number;
7773
* @property {() => void} close end every client and stop the heartbeat
7874
*/
7975
declare const HOT_DEFAULT_PATH: "/__webpack_hmr";
80-
/**
81-
* @param {StatsModule[]} modules modules
82-
* @returns {Record<string, string>} module id to name map
83-
*/
84-
declare function buildModuleMap(modules: StatsModule[]): Record<string, string>;
8576
/**
8677
* @param {number} heartbeat heartbeat interval in milliseconds
8778
* @param {Logger} logger logger
@@ -145,7 +136,6 @@ type Stats = import("webpack").Stats;
145136
type MultiStats = import("webpack").MultiStats;
146137
type StatsCompilation = import("webpack").StatsCompilation;
147138
type StatsError = import("webpack").StatsError;
148-
type StatsModule = import("webpack").StatsModule;
149139
type IncomingMessage = import("./index.js").IncomingMessage;
150140
type ServerResponse = import("./index.js").ServerResponse;
151141
type StatsOptions = NonNullable<import("webpack").Configuration["stats"]>;
@@ -188,10 +178,6 @@ type Payload = {
188178
* errors
189179
*/
190180
errors?: string[] | undefined;
191-
/**
192-
* modules
193-
*/
194-
modules?: Record<string, string> | undefined;
195181
};
196182
type EventStream = {
197183
/**

0 commit comments

Comments
 (0)