Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ Heartbeat interval (in milliseconds) used to keep the SSE connection alive when
Type: `Boolean | Object`
Default: `undefined`

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.
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.

## Hot Module Replacement client

Expand Down
4 changes: 2 additions & 2 deletions client-src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ export function setOptionsAndConnect(overrides) {
// eslint-disable-next-line jsdoc/reject-any-type
/** @typedef {any} EXPECTED_ANY */

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

/**
* @returns {{
Expand Down Expand Up @@ -295,7 +295,7 @@ function processMessage(obj) {
reporter.success();
}
if (shouldApply) {
applyUpdate(obj.hash, obj.modules, options);
applyUpdate(obj.hash, options);
}
break;
}
Expand Down
7 changes: 3 additions & 4 deletions client-src/process-update.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,9 @@ function upToDate(hash) {

/**
* @param {string} hash latest hash from the SSE payload
* @param {Record<string, string> | undefined} moduleMap module id → name map
* @param {{ reload?: boolean }} options client options
*/
export default function applyUpdate(hash, moduleMap, options) {
export default function applyUpdate(hash, options) {
const { reload } = options;

/**
Expand Down Expand Up @@ -96,7 +95,7 @@ export default function applyUpdate(hash, moduleMap, options) {
`See ${HMR_DOCS_URL} for more details.`,
);
for (const moduleId of unacceptedModules) {
log.warn(` - ${(moduleMap && moduleMap[moduleId]) || moduleId}`);
log.warn(` - ${moduleId}`);
}
performReload();
return;
Expand All @@ -107,7 +106,7 @@ export default function applyUpdate(hash, moduleMap, options) {
} else {
log.info("Updated modules:");
for (const moduleId of renewedModules) {
log.info(` - ${(moduleMap && moduleMap[moduleId]) || moduleId}`);
log.info(` - ${moduleId}`);
}
}

Expand Down
21 changes: 0 additions & 21 deletions src/hot.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
/** @typedef {import("webpack").MultiStats} MultiStats */
/** @typedef {import("webpack").StatsCompilation} StatsCompilation */
/** @typedef {import("webpack").StatsError} StatsError */
/** @typedef {import("webpack").StatsModule} StatsModule */
/** @typedef {import("./index.js").IncomingMessage} IncomingMessage */
/** @typedef {import("./index.js").ServerResponse} ServerResponse */

Expand All @@ -26,7 +25,6 @@
* @property {string=} hash hash
* @property {string[]=} warnings warnings
* @property {string[]=} errors errors
* @property {Record<string, string>=} modules modules
*/

/**
Expand Down Expand Up @@ -191,23 +189,6 @@ function extractBundles(stats) {
return [stats];
}

/**
* @param {StatsModule[]} modules modules
* @returns {Record<string, string>} module id to name map
*/
function buildModuleMap(modules) {
/** @type {Record<string, string>} */
const map = {};

for (const item of modules) {
map[/** @type {string | number} */ (item.id)] = /** @type {string} */ (
item.name
);
}

return map;
}

/**
* @param {string} action action
* @param {Stats | MultiStats} statsResult stats result
Expand Down Expand Up @@ -251,7 +232,6 @@ function publishStats(action, statsResult, eventStream, statsOptions) {
hash: stats.hash,
warnings: formatErrors(stats.warnings || []),
errors: formatErrors(stats.errors || []),
modules: buildModuleMap(stats.modules || []),
});
}
}
Expand Down Expand Up @@ -332,7 +312,6 @@ function createHot(compiler, userOptions) {
module.exports = createHot;
module.exports.HOT_DEFAULT_HEARTBEAT = HOT_DEFAULT_HEARTBEAT;
module.exports.HOT_DEFAULT_PATH = HOT_DEFAULT_PATH;
module.exports.buildModuleMap = buildModuleMap;
module.exports.createEventStream = createEventStream;
module.exports.createHot = createHot;
module.exports.formatErrors = formatErrors;
Expand Down
2 changes: 0 additions & 2 deletions test/client.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ describe("client", () => {
);
expect(processUpdate).toHaveBeenCalledWith(
"1234567890abcdef",
expect.anything(),
expect.objectContaining({ reload: true }),
);
});
Expand Down Expand Up @@ -530,7 +529,6 @@ describe("client", () => {
);
expect(processUpdate).toHaveBeenCalledWith(
"1234567890abcdef",
expect.anything(),
expect.objectContaining({ reload: false }),
);
});
Expand Down
1 change: 0 additions & 1 deletion test/helpers/sse.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import http from "node:http";
* @property {number=} time build time in ms
* @property {string[]=} errors errors
* @property {string[]=} warnings warnings
* @property {Record<string, string>=} modules module id → name map
*/

/**
Expand Down
41 changes: 29 additions & 12 deletions test/hot.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import createHot, {
buildModuleMap,
createEventStream,
formatErrors,
pathMatch,
Expand Down Expand Up @@ -138,17 +137,6 @@ describe("hot middleware (unit)", () => {
});
});

describe("buildModuleMap", () => {
it("maps id to name", () => {
expect(
buildModuleMap([
{ id: 1, name: "./a.js" },
{ id: 2, name: "./b.js" },
]),
).toEqual({ 1: "./a.js", 2: "./b.js" });
});
});

describe("createEventStream", () => {
beforeEach(() => {
jest.useFakeTimers();
Expand Down Expand Up @@ -370,6 +358,35 @@ describe("createHot", () => {
hot.close();
});

it("forwards custom statsOptions to stats.toJson", () => {
const compiler = makeFakeCompiler();
const hot = createHot(compiler, {
statsOptions: { modules: true, ids: true },
});
attachClient({ handler: hot.handle });

/** @type {EXPECTED_OBJECT} */
let receivedOptions;

compiler.emitDone({
toJson(statsOptions) {
receivedOptions = statsOptions;
return {
time: 1,
hash: "h",
warnings: [],
errors: [],
modules: [],
};
},
compilation: undefined,
});

expect(receivedOptions).toMatchObject({ modules: true, ids: true });

hot.close();
});

it("stops publishing after close() even if the compiler still emits", () => {
const compiler = makeFakeCompiler();
const hot = createHot(compiler, {});
Expand Down
14 changes: 0 additions & 14 deletions types/hot.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ declare namespace createHot {
export {
HOT_DEFAULT_HEARTBEAT,
HOT_DEFAULT_PATH,
buildModuleMap,
createEventStream,
createHot,
formatErrors,
Expand All @@ -33,7 +32,6 @@ declare namespace createHot {
MultiStats,
StatsCompilation,
StatsError,
StatsModule,
IncomingMessage,
ServerResponse,
StatsOptions,
Expand All @@ -50,7 +48,6 @@ declare const HOT_DEFAULT_HEARTBEAT: number;
/** @typedef {import("webpack").MultiStats} MultiStats */
/** @typedef {import("webpack").StatsCompilation} StatsCompilation */
/** @typedef {import("webpack").StatsError} StatsError */
/** @typedef {import("webpack").StatsModule} StatsModule */
/** @typedef {import("./index.js").IncomingMessage} IncomingMessage */
/** @typedef {import("./index.js").ServerResponse} ServerResponse */
/** @typedef {NonNullable<import("webpack").Configuration["stats"]>} StatsOptions */
Expand All @@ -68,7 +65,6 @@ declare const HOT_DEFAULT_HEARTBEAT: number;
* @property {string=} hash hash
* @property {string[]=} warnings warnings
* @property {string[]=} errors errors
* @property {Record<string, string>=} modules modules
*/
/**
* @typedef {object} EventStream
Expand All @@ -77,11 +73,6 @@ declare const HOT_DEFAULT_HEARTBEAT: number;
* @property {() => void} close end every client and stop the heartbeat
*/
declare const HOT_DEFAULT_PATH: "/__webpack_hmr";
/**
* @param {StatsModule[]} modules modules
* @returns {Record<string, string>} module id to name map
*/
declare function buildModuleMap(modules: StatsModule[]): Record<string, string>;
/**
* @param {number} heartbeat heartbeat interval in milliseconds
* @param {Logger} logger logger
Expand Down Expand Up @@ -145,7 +136,6 @@ type Stats = import("webpack").Stats;
type MultiStats = import("webpack").MultiStats;
type StatsCompilation = import("webpack").StatsCompilation;
type StatsError = import("webpack").StatsError;
type StatsModule = import("webpack").StatsModule;
type IncomingMessage = import("./index.js").IncomingMessage;
type ServerResponse = import("./index.js").ServerResponse;
type StatsOptions = NonNullable<import("webpack").Configuration["stats"]>;
Expand Down Expand Up @@ -188,10 +178,6 @@ type Payload = {
* errors
*/
errors?: string[] | undefined;
/**
* modules
*/
modules?: Record<string, string> | undefined;
};
type EventStream = {
/**
Expand Down
Loading