perf(webpack): swap babel-loader + babel-plugin-react-compiler for OXC (Rust React Compiler)#90619
Closed
roryabraham wants to merge 1 commit into
Closed
perf(webpack): swap babel-loader + babel-plugin-react-compiler for OXC (Rust React Compiler)#90619roryabraham wants to merge 1 commit into
roryabraham wants to merge 1 commit into
Conversation
Replace the single babel-loader webpack rule with a two-pass pipeline: - Pass 1 (babel-loader, configFile:false): only the three plugins with no OXC equivalent — babel-plugin-react-compiler, react-native-worklets/plugin, and @fullstory/babel-plugin-annotate-react. Babel also parses JSX/TS so these plugins see the raw source. - Pass 2 (oxc-loader): TypeScript stripping, JSX transform, class-properties, env target (node20), and all other bulk transforms. Webpack use[] runs right-to-left, so babel-loader executes first. Also removes five webpack-only Babel devDependencies that are now superseded by oxc-loader: @babel/preset-env, @babel/preset-flow, babel-plugin-react-native-web, @babel/plugin-proposal-export-namespace-from, @babel/plugin-transform-class-properties. Build time: clean 186.5s → 175.4s (−6%), warm 187.9s → 174.8s (−7%). Co-authored-by: Cursor <cursoragent@cursor.com>
|
Hey, I noticed you changed some webpack configuration files. This can break production builds. Did you remember to run a production build locally to verify they still work? |
Contributor
Author
|
not worth it yet. Will try again when React Compiler Rust port is done |
📲 Install BuildsAndroid
|
52 tasks
Contributor
Author
|
Superseded by #93980 — same changes, clean branch with GPG-signed commits. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Explanation of Change
Updated June 2026: Upgraded beyond the initial oxc-loader swap to use OXC's native Rust port of the React Compiler, available in
oxc-transform 0.136.0.New three-pass pipeline (webpack
use[]runs right-to-left)Pass 1 —
fullstory-annotation-loader.js(new custom loader, runs first on original JSX):dataComponent/dataElement/dataSourceFileprops onto JSX opening elements@babel/parser+@babel/traversein parse-only mode — no code transforms@fullstory/babel-plugin-annotate-reactwithout needing the full Babel transform pipelinePass 2 —
oxc-react-compiler-loader.js(new thin wrapper, runs second):oxc-transformdirectly: React Compiler → JSX transform → TypeScript strip → env target — all in one Rust passoxc-transform 0.136.0(pinned viapackage.json overrides; the NAPI binding was removed in 0.137.0 — see oxc-project/oxc#23590, re-exposure in progress)babel-plugin-react-compiler's default bailout behaviour (workaround for oxc-project/oxc#23587)Pass 3 —
babel-loader(runs last, worklets only):react-native-worklets/pluginonly — serialises'worklet'functions for UI-thread executionincludeModules(Rule B) skip React Compiler but still go through OXC for JSX/TS transforms, split by extension to avoid.tsgeneric syntax being confused with JSXRemoved devDependencies (now superseded by OXC)
@babel/preset-react— JSX transform now handled by OXC@babel/preset-typescript— TypeScript stripping now handled by OXC@babel/preset-env(removed in May 2026 commit)@babel/preset-flow(removed in May 2026 commit)babel-plugin-react-native-web(removed in May 2026 commit)@babel/plugin-proposal-export-namespace-from(removed in May 2026 commit)@babel/plugin-transform-class-properties(removed in May 2026 commit)Retained:
babel-plugin-react-compiler(still used directly by the Metrobabel.config.jsfor mobile builds),@babel/plugin-proposal-class-properties,@babel/plugin-transform-export-namespace-from(both used by Metro)Build timing (measured locally on the
rory-oxc-loaderworktree)rm -rf dist/ && npm run buildnpm run build(after clean)Correctness verified
dataComponentannotations present in main and vendors bundlesuseMemoCachepresent in 15 locations across 2 bundlesOpen items / known limitations
oxc-transform 0.136.0is pinned because the React Compiler NAPI binding was removed in 0.137.0 (oxc-project/oxc#23590). Once it is re-exposed, we can unpin.babel-plugin-react-compilerwas silently skipping. Tracked by oxc-project/oxc#23587 for proper silent-skip behaviour.npm run web) and Reassure perf test (npm run test:perf) not yet run — this is a POC branch.Rollback: Revert the three loader files and
package.jsonchanges.Fixed Issues
$
PROPOSAL:
Tests
npm run buildand verify it compiles with 0 errorsnpm run weband load the app in a browser — verify it loads, you can log in, and navigate to a reportOffline tests
N/A — build tooling change only.
QA Steps [No QA]
Build pipeline change only. No user-visible behaviour modified.
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
N/A — build tooling change onlyAndroid: mWeb Chrome
N/A — build tooling change onlyiOS: Native
N/A — build tooling change onlyiOS: mWeb Safari
N/A — build tooling change onlyMacOS: Chrome / Safari
N/A — build tooling change only (smoke test pending)