Skip to content

Commit c48649f

Browse files
committed
feat(client): collapse the updated-modules list in the console (#2361)
The success path now logs a one-line summary with the module count at the default "info" level, and the per-module detail as a collapsed console group visible from the "log" level up (webpack's runtime logger gates groups below that level). The unaccepted-modules warning list stays flat: it is diagnostic output for the failing case. Ref webpack/webpack-hot-middleware#311
1 parent 1c10209 commit c48649f

2 files changed

Lines changed: 46 additions & 6 deletions

File tree

client-src/process-update.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,13 @@ export default function applyUpdate(hash, options) {
108108
if (!renewedModules || renewedModules.length === 0) {
109109
log.info("Nothing hot updated.");
110110
} else {
111-
log.info("Updated modules:");
111+
log.info(`Hot updated ${renewedModules.length} modules.`);
112+
// Detail as a collapsed group, visible from the "log" level up.
113+
log.groupCollapsed("Updated modules:");
112114
for (const moduleId of renewedModules) {
113-
log.info(` - ${moduleId}`);
115+
log.log(` - ${moduleId}`);
114116
}
117+
log.groupEnd();
115118
}
116119

117120
if (upToDate()) {

test/process-update.test.js

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,21 +189,58 @@ describe("process-update", () => {
189189
return spy.mock.calls.some((call) => call.join(" ").includes(text));
190190
}
191191

192-
it("lists the updated modules at the default info level", async () => {
192+
beforeEach(() => {
193+
if (typeof console.groupCollapsed !== "function") {
194+
console.groupCollapsed = () => {};
195+
}
196+
if (typeof console.groupEnd !== "function") {
197+
console.groupEnd = () => {};
198+
}
199+
jest.spyOn(console, "groupCollapsed").mockImplementation(() => {});
200+
jest.spyOn(console, "groupEnd").mockImplementation(() => {});
201+
});
202+
203+
it("logs a one-line summary at the default info level", async () => {
204+
applyUpdate = loadApplyUpdate(
205+
makeFakeHot({
206+
checkResult: ["./a.js", "./b.js"],
207+
applyImpl: () => Promise.resolve(["./a.js", "./b.js"]),
208+
}),
209+
);
210+
211+
applyUpdate("new-hash", { reload: true });
212+
globalThis.__webpack_hash__ = "new-hash";
213+
await flushPromises();
214+
215+
expect(logged(console.info, "Hot updated 2 modules.")).toBe(true);
216+
// Groups are gated below the "log" level.
217+
expect(console.groupCollapsed).not.toHaveBeenCalled();
218+
expect(logged(console.log, "./a.js")).toBe(false);
219+
});
220+
221+
it("adds a collapsed group with the module detail at the log level", async () => {
193222
applyUpdate = loadApplyUpdate(
194223
makeFakeHot({
195224
checkResult: ["./a.js", "./b.js"],
196225
applyImpl: () => Promise.resolve(["./a.js", "./b.js"]),
197226
}),
198227
);
228+
setLogLevel("log");
199229

200230
applyUpdate("new-hash", { reload: true });
201231
globalThis.__webpack_hash__ = "new-hash";
202232
await flushPromises();
203233

204-
expect(logged(console.info, "Updated modules:")).toBe(true);
205-
expect(logged(console.info, "./a.js")).toBe(true);
206-
expect(logged(console.info, "./b.js")).toBe(true);
234+
expect(logged(console.info, "Hot updated 2 modules.")).toBe(true);
235+
expect(
236+
logged(
237+
/** @type {jest.Mock} */ (console.groupCollapsed),
238+
"Updated modules:",
239+
),
240+
).toBe(true);
241+
expect(logged(console.log, "./a.js")).toBe(true);
242+
expect(logged(console.log, "./b.js")).toBe(true);
243+
expect(console.groupEnd).toHaveBeenCalled();
207244
});
208245
});
209246
});

0 commit comments

Comments
 (0)