Skip to content

Commit 5723799

Browse files
committed
Merge branch 'jongsun/build/webpack/react-compiler-debug-mode' into jongsun/build/enable-react-compiler-webpack
2 parents 54d4402 + 68e28d9 commit 5723799

File tree

4 files changed

+144
-15
lines changed

4 files changed

+144
-15
lines changed

development/webpack/utils/cli.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,13 @@ function getOptions(
356356
group: toOrange('Security:'),
357357
type: 'boolean',
358358
},
359+
reactCompilerVerbose: {
360+
array: false,
361+
default: false,
362+
description: 'Enables/disables React Compiler verbose mode',
363+
group: toOrange('Developer assistance:'),
364+
type: 'boolean',
365+
},
359366

360367
dryRun: {
361368
array: false,

development/webpack/utils/config.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { join } from 'node:path';
22
import { readFileSync } from 'node:fs';
33
import { parse } from 'dotenv';
4-
import type { ReactCompilerLoaderOption } from 'react-compiler-webpack';
54
import { setEnvironmentVariables } from '../../build/set-environment-variables';
65
import type { Variables } from '../../lib/variables';
76
import type { BuildTypesConfig, BuildType } from '../../lib/build-type';
@@ -192,6 +191,3 @@ function loadConfigVars(
192191

193192
return definitions;
194193
}
195-
export const reactCompilerOptions = {
196-
target: '17',
197-
} as const satisfies ReactCompilerLoaderOption;
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import {
2+
type ReactCompilerLoaderOption,
3+
defineReactCompilerLoaderOption,
4+
reactCompilerLoader,
5+
} from 'react-compiler-webpack';
6+
import type { Logger } from 'babel-plugin-react-compiler';
7+
8+
/**
9+
* React Compiler logger that tracks compilation statistics
10+
*/
11+
class ReactCompilerLogger {
12+
private compiledCount = 0;
13+
14+
private skippedCount = 0;
15+
16+
private errorCount = 0;
17+
18+
private todoCount = 0;
19+
20+
private compiledFiles: string[] = [];
21+
22+
private skippedFiles: string[] = [];
23+
24+
private errorFiles: string[] = [];
25+
26+
private todoFiles: string[] = [];
27+
28+
logEvent(
29+
filename: string | null,
30+
event: { kind: string; detail: { options: { category: string } } },
31+
) {
32+
if (filename === null) {
33+
return;
34+
}
35+
switch (event.kind) {
36+
case 'CompileSuccess':
37+
this.compiledCount++;
38+
this.compiledFiles.push(filename);
39+
console.log(`✅ Compiled: ${filename}`);
40+
break;
41+
case 'CompileSkip':
42+
this.skippedCount++;
43+
this.skippedFiles.push(filename);
44+
break;
45+
case 'CompileError':
46+
if (event.detail?.options?.category === 'Todo') {
47+
this.todoCount++;
48+
this.todoFiles.push(filename);
49+
break;
50+
}
51+
this.errorCount++;
52+
this.errorFiles.push(filename);
53+
console.error(
54+
`❌ React Compiler error in ${filename}: ${JSON.stringify(event.detail?.options) || 'Unknown error'}`,
55+
);
56+
break;
57+
default:
58+
// Ignore other event types
59+
break;
60+
}
61+
}
62+
63+
getStats() {
64+
return {
65+
compiled: this.compiledCount,
66+
skipped: this.skippedCount,
67+
errors: this.errorCount,
68+
unsupported: this.todoCount,
69+
total:
70+
this.compiledCount +
71+
this.skippedCount +
72+
this.errorCount +
73+
this.todoCount,
74+
compiledFiles: this.compiledFiles,
75+
skippedFiles: this.skippedFiles,
76+
errorFiles: this.errorFiles,
77+
unsupportedFiles: this.todoFiles,
78+
};
79+
}
80+
81+
logSummary() {
82+
const stats = this.getStats();
83+
console.log('\n📊 React Compiler Statistics:');
84+
console.log(` ✅ Compiled: ${stats.compiled} files`);
85+
console.log(` ⏭️ Skipped: ${stats.skipped} files`);
86+
console.log(` ❌ Errors: ${stats.errors} files`);
87+
console.log(` 🔍 Unsupported: ${stats.unsupported} files`);
88+
console.log(` 📦 Total processed: ${stats.total} files`);
89+
}
90+
}
91+
92+
// Create a singleton logger instance
93+
const reactCompilerLogger = new ReactCompilerLogger();
94+
95+
/**
96+
* Get the React Compiler logger instance for accessing statistics
97+
*/
98+
export function getReactCompilerLogger(): ReactCompilerLogger {
99+
return reactCompilerLogger;
100+
}
101+
102+
export const getReactCompilerLoader = (
103+
target: ReactCompilerLoaderOption['target'],
104+
verbose: boolean,
105+
) => {
106+
const reactCompilerOptions = {
107+
target,
108+
logger: verbose ? (reactCompilerLogger as Logger) : undefined,
109+
} as const satisfies ReactCompilerLoaderOption;
110+
111+
return {
112+
loader: reactCompilerLoader,
113+
options: defineReactCompilerLoaderOption(reactCompilerOptions),
114+
};
115+
};

development/webpack/webpack.config.ts

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,6 @@ import rtlCss from 'postcss-rtlcss';
1818
import autoprefixer from 'autoprefixer';
1919
import discardFonts from 'postcss-discard-font-face';
2020
import type ReactRefreshPluginType from '@pmmmwh/react-refresh-webpack-plugin';
21-
import {
22-
defineReactCompilerLoaderOption,
23-
reactCompilerLoader,
24-
} from 'react-compiler-webpack';
2521
import tailwindcss from 'tailwindcss';
2622
import { loadBuildTypesConfig } from '../lib/build-type';
2723
import {
@@ -38,7 +34,11 @@ import { transformManifest } from './utils/plugins/ManifestPlugin/helpers';
3834
import { parseArgv, getDryRunMessage } from './utils/cli';
3935
import { getCodeFenceLoader } from './utils/loaders/codeFenceLoader';
4036
import { getSwcLoader } from './utils/loaders/swcLoader';
41-
import { getVariables, reactCompilerOptions } from './utils/config';
37+
import {
38+
getReactCompilerLoader,
39+
getReactCompilerLogger,
40+
} from './utils/loaders/reactCompilerLoader';
41+
import { getVariables } from './utils/config';
4242
import { ManifestPlugin } from './utils/plugins/ManifestPlugin';
4343
import { getLatestCommit } from './utils/git';
4444

@@ -216,13 +216,29 @@ if (args.progress) {
216216
const { ProgressPlugin } = require('webpack');
217217
plugins.push(new ProgressPlugin());
218218
}
219+
220+
if (args.reactCompilerVerbose) {
221+
plugins.push({
222+
apply(compiler) {
223+
compiler.hooks.done.tap('ReactCompilerStatsPlugin', () => {
224+
const logger = getReactCompilerLogger();
225+
logger.logSummary();
226+
});
227+
},
228+
} as WebpackPluginInstance);
229+
}
230+
219231
// #endregion plugins
220232

221233
const swcConfig = { args, browsersListQuery, isDevelopment };
222234
const tsxLoader = getSwcLoader('typescript', true, safeVariables, swcConfig);
223235
const jsxLoader = getSwcLoader('ecmascript', true, safeVariables, swcConfig);
224236
const npmLoader = getSwcLoader('ecmascript', false, {}, swcConfig);
225237
const cjsLoader = getSwcLoader('ecmascript', false, {}, swcConfig, 'commonjs');
238+
const reactCompilerLoader = getReactCompilerLoader(
239+
'17',
240+
args.reactCompilerVerbose,
241+
);
226242

227243
const config = {
228244
entry,
@@ -328,12 +344,7 @@ const config = {
328344
{
329345
test: /(?!\.(?:test|stories|container))\.(?:m?[jt]s|[jt]sx)$/u,
330346
include: UI_DIR_RE,
331-
use: [
332-
{
333-
loader: reactCompilerLoader,
334-
options: defineReactCompilerLoaderOption(reactCompilerOptions),
335-
},
336-
],
347+
use: [reactCompilerLoader],
337348
},
338349
// own typescript, and own typescript with jsx
339350
{

0 commit comments

Comments
 (0)