はじめに:React Compilerの登場と、Next.jsにおける疑問
2025/04/21、Reactチームは待望のReact Compilerの安定版リリース候補を発表しました。このCompilerは、Reactコンポーネントが不要な再レンダリングを自動的にスキップできるようにコードを最適化し、開発者が手動でuseMemo
やuseCallback
といった最適化フックを記述する負担を減らすことを目指しています。
ただ、React CompilerがBabelプラグインとしてしか提供されていない点が気になります。近年、Next.jsは高速なRustベースのコンパイラであるSWCを積極的に導入し、Babelへの依存を減らしてきました。それによってビルド速度が劇的に向上したことを体感している方も多いでしょう。
SWCが主流となっているNext.jsにおいて、BabelプラグインであるReact Compilerはどのように統合されているのでしょうか?
公式ドキュメントでの説明がふわっとしてたので、2025/08/22 時点のNext.js Canary版のソースコードを使って解説します。
なお、実際にNext.jsでReact Compilerを有効にした際に、どのようなコードがビルドされるのか、より具体的な変換結果については、mugiさんの記事が非常に参考になります:
結論:SWCとBabelのハイブリッド戦略
Next.jsがReact Compilerを統合するために採用しているアプローチは、SWCとBabelのハイブリッド戦略です。
端的に言えば、Next.jsは以下のステップでReact Compilerを実行しています。
- SWC (Rust) でソースコードをパースし、そのASTを利用して、React Compilerを適用すべきファイルかどうかを高速に判定
- 判定で
true
になったファイルのみ、Babel Loaderを介してReact CompilerのBabelプラグインが実行される
つまり、全てのJavaScript/TypeScriptファイルをBabelに通すのではなく、SWCが前処理として対象ファイルを絞り込むことで、SWCの高速性を最大限に活かしつつ、BabelプラグインであるReact Compilerの機能を統合しているのです。
ではこれが具体的にコードレベルでどのように実現されているのかを見ていきましょう。
コードリードしていく
Next.jsは、Rustで書かれたSWCのカスタムトランスフォームを使用して、1つのファイルがReact Compilerの対象となるべきかを判定します。
このRustコードでは、SWCがパースしたASTを使い、以下のような特徴を持つ関数やコンポーネントを探します。
-
大文字で始まる関数名: 通常のReactコンポーネントの命名規則(例:
function MyComponent() {...}
) - “use”で始まる関数名: React Hooksっぽいもの
-
export default
された関数 - これらの関数内でJSX要素が使われているか
この判定ロジックは、偽陰性(本当はコンパイラを適用すべきなのに誤って不要と判断してしまう)が低くなるように判定することを重視していることを感じます。
Rustで実装された判定ロジックをTSで叩くバインディング:
このとき、RustからTypeScriptに渡されるデータはtrue
かfalse
という極めて小さな情報である点が重要です。プロセスを跨いでAST全体を渡すような高コストな処理は発生しません。
この判定結果を受け取ってBabelローダーの設定を動的に生成しています:
ここで、SWCから渡された判定結果がtrue
の場合、React CompilerのBabelプラグインが設定に追加されます。
また、この部分で言及されているstandalone
モードとは、Next.jsが提供するデフォルトのビルドプロセスでSWCローダーがメインで使用される場合を指します。もしアプリケーション開発者が独自に.babelrc
などのBabel設定ファイルを設置している場合、Next.jsは開発者の設定を優先するため、React Compilerプラグインはご自身で設定いただく必要があります。
おわり
React Compilerを適用する対象として、node_modules
を除外するだけではちょっと物足りなかったようです。
結果的にBabel/SWCが協調してる珍妙なコードになっていますが、swcネイティブのReact Compilerが出るまでの幻かもしれません。
ちなみにこの変更はさりげなく行われています:https://github.com/vercel/next.js/pull/75605
本記事では、Next.jsがReact Compilerをどのように実行しているかについて、その内部実装をソースコードレベルで紐解きました。
Views: 0