Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

[v6] Use the Rust React Compiler via jsc.transform.reactCompiler

オープン
#1,423 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
5/5
見積もり時間
1週間以上
初心者へのやさしさ
42/100
issue の種類
機能追加
明瞭さ
おおむね明確
活発さ
活発
技術スタック
react, typescript, webpack

調査の方向性

packages/repack/src/loaders/babelSwcLoader/swc.ts と getSwcLoaderOptions/getJsTransformRules のエントリーポイントから始め、既存の transform テストを読み、実行します。react-native-worklets/plugin と packages/plugin-reanimated を使った Babel-then-SWC の動作を検証し、その後、サポートされるオプションとサポートされないオプション、バージョン処理、ドキュメントを対象にして、オプトイン経路がテストおよび文書化されるようにします。

索引モデルが issue の本文から書いたものです。

説明

area:repack type:feature

Motivation

The React Compiler has been ported to Rust and is exposed through builtin:swc-loader as jsc.transform.reactCompiler since Rspack 2.1. Rspack measures the Rust implementation at 7–13x the speed of babel-plugin-react-compiler.

Re.Pack has no React Compiler support of any kind today — no mention in packages/, website/src or the templates. Users who want it add babel-plugin-react-compiler to their own babel.config.js, and because of how babel-swc-loader partitions work, that plugin then runs on the Babel side for every component file in the app.

Part of #1414 (Roadmap to V6), which lists "rust react compiler support" as a deliverable. Adjacent to #1422 (SWC setup rework) — both touch getSwcLoaderOptions, and the config surface should be designed once.

Why it lands on the Babel side today

babelSwcLoader reads the project's Babel config, partitions the detected plugins into "SWC can do this" vs "Babel must do this", then runs Babel with excludePlugins: supportedSwcTransforms followed by SWC:

const { includedSwcTransforms, supportedSwcTransforms, swcConfig } =
  partitionTransforms(this.resourcePath, detectedBabelTransforms);
const babelResult = await transform(source, baseBabelConfig, {
  excludePlugins: supportedSwcTransforms,
  ...
});

babel-plugin-react-compiler appears in none of SWC_SUPPORTED_NORMAL_RULES / SWC_SUPPORTED_CONFIGURABLE_RULES / SWC_SUPPORTED_CUSTOM_RULES in swc.ts, so it is never excluded and always runs through Babel. React Compiler is by far the most expensive Babel plugin in a typical RN app's config — it does whole-function dataflow analysis on every component. Mapping it into jsc.transform.reactCompiler is the single biggest remaining Babel offload available to us.

Verified behaviour

All of the below was checked against @rspack/core@2.1.6 via experiments.swc.transformSync.

It works, and composes with the RN-shaped config we already emit:

config result
reactCompiler: true memoized, emits react/compiler-runtime
+ env.include (RN-style transform list from getSwcLoaderOptions) memoized
+ module.type: 'commonjs' memoized, emits require("react/compiler-runtime")

The last row matters — getSwcLoaderOptions emits module.type: 'commonjs' by default, and the compiler runtime import survives the module transform correctly.

The accepted option surface is narrower than the Babel plugin's. Probed exhaustively:

option accepted values
target '17', '18', '19' — '20' rejected
compilationMode 'infer', 'annotation', 'all', 'syntax'
panicThreshold 'none', 'critical_errors', 'all_errors' (lowercase only)
anything else rejected — expected boolean or object

Notably sources is rejected. The Babel plugin uses it to scope which files get compiled; here that has to be expressed with the loader rule's include / exclude instead. Same for the enable* escape hatches (e.g. enableTreatRefLikeIdentifiersAsRefs) — projects depending on those cannot move off Babel yet.

Version floor. @rspack/core >= 2.1.0. #1414 currently targets "Rspack 2+", which is not sufficient for this; the floor needs to be 2.1 if this ships as a supported feature (or the option needs a version guard, which Re.Pack already has machinery for — see getRspackMajorVersion / isRspack2 in src/helpers/rspackVersion.ts).

React version. The workspace catalog is on react: 19.2.3, where react/compiler-runtime is built in and target can be omitted. React 17/18 projects need an explicit target and the separate react-compiler-runtime package installed — that's a user-facing install step we have to document, not something we can do for them.

Proposed direction

Two independent surfaces, both opt-in and off by default:

  1. babel-swc-loader (the default path). Add babel-plugin-react-compiler to the custom-transform map in swc.ts so a project that already has it in babel.config.js gets it lifted to SWC automatically, with its Babel options translated to the reactCompiler shape. Because the surface is narrower, the mapping must detect unsupported options and leave the plugin on the Babel side rather than silently dropping them — a sources or enable* option present means "keep using Babel for this project".

  2. getSwcLoaderOptions / getJsTransformRules (the SWC-native path). Add a reactCompiler?: boolean | { target?, compilationMode?, panicThreshold? } option that maps to jsc.transform.reactCompiler, defaulting to off.

Ordering caveat to verify

In babelSwcLoader, Babel runs first and SWC second, so lifting React Compiler to SWC moves it from "before everything" to "after the remaining Babel plugins". JSX survives the Babel pass (transform-react-jsx is in the SWC-supported set, so it is excluded from Babel), which is the main thing React Compiler needs to see intact — but this needs a real test, not an assumption. Projects with worklet-style plugins that rewrite function bodies (react-native-worklets/plugin is in apps/tester-app/babel.config.js, and Reanimated is a first-party integration in packages/plugin-reanimated) are the interesting case: those stay on the Babel side and would now run before the compiler instead of after it.

Scope

Core
  • Add reactCompiler to getSwcLoaderOptions (+ thread through getJsTransformRules), off by default, mapping to jsc.transform.reactCompiler
  • Guard the option behind Rspack >= 2.1 with a clear error/warning on older majors and on webpack (builtin:swc-loader is Rspack-only)
  • Map babel-plugin-react-compiler in swc.ts's SWC_SUPPORTED_CUSTOM_RULES, translating target / compilationMode / panicThreshold
  • Bail out of the mapping (leave the plugin on Babel) when the project passes options SWC does not accept — sources, enable*, anything outside the three above
  • Decide whether target is inferred from the resolved react version or left explicit
Apps and tests
  • Verify the Babel-then-SWC ordering is safe, specifically alongside react-native-worklets/plugin and packages/plugin-reanimated
  • Enable React Compiler in apps/tester-app (or a variant) so the path is exercised on device, not just in unit tests
  • Unit tests for the swc.ts mapping, including the unsupported-option bail-out
  • Snapshot coverage in getSwcLoaderOptions tests
Docs
  • New guide page for React Compiler — how to enable it on both loader paths, the Rspack >= 2.1 requirement, and the React 17/18 target + react-compiler-runtime install step
  • Document the option gap vs babel-plugin-react-compiler (sources → use rule include/exclude) and when a project should stay on Babel
  • Update website/src/latest/api/utils/get-swc-loader-options.md and get-js-transform-rules.md

Open questions

  • Does v6 raise the Rspack floor to 2.1 (making this unconditional), or keep 2.0 and version-guard the option?
  • Should Re.Pack enable React Compiler by default for new projects in templates/, follow React Native's own default, or leave it entirely opt-in?
  • Is auto-lifting from babel.config.js the right default for babel-swc-loader, or should it require an explicit loader option? Auto-lifting is the bigger win but silently changes where a plugin runs in the pipeline.
主要言語
TypeScript
スター
1.9k
フォーク
164
平均マージ
10日 13時間
マージ済み PR(30日)
10

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

callstack/repack のほかの issue

callstack/repack の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。