Skip to content

Commit 1e7d43d

Browse files
authored
feat: report Rspack compilation progress in dev server logs (#1248)
1 parent c53900d commit 1e7d43d

File tree

8 files changed

+69
-52
lines changed

8 files changed

+69
-52
lines changed

.changeset/four-regions-report.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@callstack/repack": minor
3+
---
4+
5+
Report Rspack compilation progress in the DevServer logs

packages/dev-server/src/plugins/compiler/compilerPlugin.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ async function compilerPlugin(
4747
);
4848
};
4949

50+
// immediately send 1% progress
51+
setImmediate(() => sendProgress({ completed: 1, total: 100 }));
52+
5053
try {
5154
const asset = await delegate.compiler.getAsset(
5255
filepath,

packages/repack/src/commands/rspack/Compiler.ts

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import fs from 'node:fs';
22
import path from 'node:path';
3-
import type { Server } from '@callstack/repack-dev-server';
3+
import type { SendProgress, Server } from '@callstack/repack-dev-server';
44
import { rspack } from '@rspack/core';
55
import type {
66
MultiCompiler,
@@ -22,6 +22,7 @@ export class Compiler {
2222
assetsCache: Record<string, Record<string, CompilerAsset> | undefined> = {};
2323
statsCache: Record<string, StatsCompilation | undefined> = {};
2424
resolvers: Record<string, Array<(error?: Error) => void>> = {};
25+
progressSenders: Record<string, SendProgress[]> = {};
2526
isCompilationInProgress = false;
2627
// late-init
2728
devServerContext!: Server.DelegateContext;
@@ -31,6 +32,28 @@ export class Compiler {
3132
private reporter: Reporter,
3233
private rootDir: string
3334
) {
35+
const handler = (platform: string, value: number) => {
36+
const percentage = Math.floor(value * 100);
37+
this.progressSenders[platform]?.forEach((sendProgress) => {
38+
sendProgress({ completed: percentage, total: 100 });
39+
});
40+
41+
reporter.process({
42+
issuer: 'DevServer',
43+
message: [{ progress: { value, platform } }],
44+
timestamp: Date.now(),
45+
type: 'progress',
46+
});
47+
};
48+
49+
configs.forEach((config) => {
50+
config.plugins?.push(
51+
new rspack.ProgressPlugin((percentage) =>
52+
handler(config.name as string, percentage)
53+
)
54+
);
55+
});
56+
3457
this.compiler = rspack.rspack(configs);
3558
this.platforms = configs.map((config) => config.name as string);
3659
this.filesystem = memfs.createFsFromVolume(new memfs.Volume());
@@ -53,6 +76,19 @@ export class Compiler {
5376
this.resolvers[platform] = [];
5477
}
5578

79+
private addProgressSender(platform: string, callback?: SendProgress) {
80+
if (!callback) return;
81+
this.progressSenders[platform] = this.progressSenders[platform] ?? [];
82+
this.progressSenders[platform].push(callback);
83+
}
84+
85+
private removeProgressSender(platform: string, callback?: SendProgress) {
86+
if (!callback) return;
87+
this.progressSenders[platform] = this.progressSenders[platform].filter(
88+
(item) => item !== callback
89+
);
90+
}
91+
5692
setDevServerContext(ctx: Server.DelegateContext) {
5793
this.devServerContext = ctx;
5894
}
@@ -190,14 +226,21 @@ export class Compiler {
190226
});
191227
}
192228

193-
async getAsset(filename: string, platform: string): Promise<CompilerAsset> {
229+
async getAsset(
230+
filename: string,
231+
platform: string,
232+
sendProgress?: SendProgress
233+
): Promise<CompilerAsset> {
194234
// Return file from assetsCache if exists
195235
const fileFromCache = this.assetsCache[platform]?.[filename];
196236
if (fileFromCache) {
197237
return fileFromCache;
198238
}
199239

240+
this.addProgressSender(platform, sendProgress);
241+
200242
if (!this.isCompilationInProgress) {
243+
this.removeProgressSender(platform, sendProgress);
201244
return Promise.reject(
202245
new Error(
203246
`File ${filename} for ${platform} not found in compilation assets (no compilation in progress)`
@@ -209,6 +252,7 @@ export class Compiler {
209252
// Add new resolver to be executed when compilation is finished
210253
this.resolvers[platform] = (this.resolvers[platform] ?? []).concat(
211254
(error?: Error) => {
255+
this.removeProgressSender(platform, sendProgress);
212256
if (error) {
213257
reject(error);
214258
} else {
@@ -230,13 +274,14 @@ export class Compiler {
230274

231275
async getSource(
232276
filename: string,
233-
platform: string | undefined
277+
platform: string | undefined,
278+
sendProgress?: SendProgress
234279
): Promise<string | Buffer> {
235280
if (DEV_SERVER_ASSET_TYPES.test(filename)) {
236281
if (!platform) {
237282
throw new CLIError(`Cannot detect platform for ${filename}`);
238283
}
239-
const asset = await this.getAsset(filename, platform);
284+
const asset = await this.getAsset(filename, platform, sendProgress);
240285
return asset.data;
241286
}
242287

packages/repack/src/commands/rspack/start.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,9 @@ export async function start(
142142

143143
return {
144144
compiler: {
145-
getAsset: (url, platform) => {
145+
getAsset: (url, platform, sendProgress) => {
146146
const { resourcePath } = parseUrl(url, platforms);
147-
return compiler.getSource(resourcePath, platform);
147+
return compiler.getSource(resourcePath, platform, sendProgress);
148148
},
149149
getMimeType: (filename) => {
150150
return getMimeType(filename);

packages/repack/src/commands/webpack/Compiler.ts

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -105,25 +105,12 @@ export class Compiler extends EventEmitter {
105105
this.emit(value.event, value.error);
106106
} else if (value.event === 'progress') {
107107
this.progressSenders[platform].forEach((sendProgress) => {
108-
if (Number.isNaN(value.total)) return;
109-
if (Number.isNaN(value.completed)) return;
110-
sendProgress({
111-
total: value.total,
112-
completed: value.completed,
113-
});
108+
const percentage = Math.floor(value.percentage * 100);
109+
sendProgress({ completed: percentage, total: 100 });
114110
});
115111
this.reporter.process({
116112
issuer: 'DevServer',
117-
message: [
118-
{
119-
progress: {
120-
value: value.percentage,
121-
label: value.label,
122-
message: value.message,
123-
platform,
124-
},
125-
},
126-
],
113+
message: [{ progress: { value: value.percentage, platform } }],
127114
timestamp: Date.now(),
128115
type: 'progress',
129116
});

packages/repack/src/commands/webpack/CompilerWorker.ts

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,8 @@ async function main(opts: WebpackWorkerOptions) {
2525
});
2626

2727
config.plugins = (config.plugins ?? []).concat(
28-
new webpack.ProgressPlugin({
29-
entries: false,
30-
dependencies: false,
31-
modules: true,
32-
handler: (percentage, message, text) => {
33-
const [, completed, total] = /(\d+)\/(\d+) modules/.exec(text) ?? [];
34-
postMessage({
35-
event: 'progress',
36-
completed: Number.parseInt(completed, 10),
37-
total: Number.parseInt(total, 10),
38-
percentage: percentage,
39-
label: message,
40-
message: text,
41-
});
42-
},
28+
new webpack.ProgressPlugin((percentage) => {
29+
postMessage({ event: 'progress', percentage: percentage });
4330
})
4431
);
4532

packages/repack/src/commands/webpack/types.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,7 @@ export namespace WorkerMessages {
4444

4545
export interface ProgressMessage extends BaseWorkerMessage {
4646
event: 'progress';
47-
total: number;
48-
completed: number;
4947
percentage: number;
50-
label: string;
51-
message: string;
5248
}
5349

5450
export interface ErrorMessage extends BaseWorkerMessage {

packages/repack/src/logging/reporters/ConsoleReporter.ts

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -176,14 +176,9 @@ class InteractiveConsoleReporter implements Reporter {
176176

177177
private processProgress = throttle((log: LogEntry) => {
178178
const {
179-
progress: { value, label, message, platform },
179+
progress: { value, platform },
180180
} = log.message[0] as {
181-
progress: {
182-
value: number;
183-
label: string;
184-
message: string;
185-
platform: string;
186-
};
181+
progress: { value: number; platform: string };
187182
};
188183

189184
const percentage = Math.floor(value * 100);
@@ -195,12 +190,11 @@ class InteractiveConsoleReporter implements Reporter {
195190
timestamp: log.timestamp,
196191
issuer: log.issuer,
197192
type: 'info',
198-
message: [`Compiling ${platform}: ${percentage}% ${label}`].concat(
199-
...(message ? [`(${message})`] : [])
200-
),
193+
message: [`Compiling ${platform}: ${percentage}%`],
201194
})}\n`
202195
);
203-
}, 1000);
196+
// match rspack progressplugin throttle for now
197+
}, 200);
204198

205199
private prettifyLog(log: LogEntry) {
206200
let body = '';

0 commit comments

Comments
 (0)