本日、React Native 0.80 をリリースできることを嬉しく思います!このリリースでは、React Native にバンドルする React のバージョンを最新の安定版である 19.1.0 に更新しました。また、JS API の安定性向上も多数含まれており、deep imports(深いパスからのインポート)に対して警告を出すようにし、より正確で安全な型を提供する新しいオプトイン方式の Strict TypeScript API を提供します。さらに、React Native の Legacy Architecture(レガシーアーキテクチャ)は公式に凍結され、Legacy Architecture の完全廃止後に動作しなくなる API について警告が表示されるようになります。
\
ハイライト\
\
- JavaScript の deep imports 非推奨化\
- Legacy Architecture の凍結と警告表示\
- React 19.1.0 の同梱\
- 実験的: iOS の依存ライブラリをプリビルドで提供(React Native iOS dependencies are now prebuilt)
\
JavaScript deep imports の非推奨化\
このリリースでは、React Native の公開 JavaScript API を改善・安定化するための取り組みを行っています。その第一歩として、アプリやフレームワークがインポートできる API をより明確に範囲指定します。これに伴い、React Native からの deep imports を正式に非推奨とし(see RFC)、ESLint と JS コンソール経由で警告を導入します。これらの警告はプロジェクトのソースコード内からのインポートに限定され、でオプトアウトすることができます。ただし、将来のリリースで deep imports を React Native の API から削除する予定であるため、deep imports はルートインポートに置き換えるべきです。
// Before - import from subpath
import { Alert } from 'react-native/Libraries/Alert/Alert' ;
// After - import from react-native
import { Alert } from 'react-native' ;
一部の API はルートからエクスポートされておらず、deep imports がないと利用できなくなります。これは React Native の API の総面積を削減するために意図的に行っているものです。今後少なくとも次の 2 リリースにかけて、どの API をエクスポートするかコミュニティと協議して最終決定します。フィードバックをお寄せください。詳しくは専用記事 Moving Towards a Stable JavaScript API をご参照ください。
\
Opt-in Strict TypeScript API(オプトイン厳格 TypeScript API)\
上記の公開 API の再定義に合わせて、0.80 では react-native パッケージ向けの新しい TypeScript 型セット(Strict TypeScript API)を提供します。Strict TypeScript API にオプトインすることは、将来の安定した JavaScript API のプレビューを利用することを意味します。新しい型の特徴は次の通りです。
\
- ソースコードから直接生成されている — カバレッジと正確性が向上し、より強力な互換性保証が期待できます。\
- React Native の index ファイルに限定されている — 公開 API を厳密に定義するため、内部ファイルの変更で API が壊れることが少なくなります。
既存の型定義と並行して提供されるため、準備ができたタイミングで移行できます。標準的な React Native API を使っている多くのアプリはほとんど変更なくバリデートできるはずです。新規作成されたアプリや早期導入者には、tsconfig.json でのオプトインを強く推奨します。コミュニティの準備が整い次第、Strict TypeScript API は deep imports の削除と同期して将来的にデフォルト API になります。詳しくは専用記事 Moving Towards a Stable JavaScript API をご覧ください。
\
Legacy Architecture の凍結と警告\
New Architecture は 0.76 以降の既定選択肢であり、多くのプロジェクトやツールが恩恵を受けているという報告をいただいています。最近、Legacy Architecture を凍結済みと見なすことを共有しました。これ以降、Legacy Architecture に対して新しいバグ修正や機能開発は行わず、リリース作業中に Legacy Architecture のテストも停止します。
移行を円滑にするため、バグや回帰が発生している場合に New Architecture をオプトアウトできる仕組みは継続して提供します。しかし、2 つのアーキテクチャを同時に維持することは大きな負担であり、ランタイム性能、アプリサイズ、コードベースの保守に影響します。したがって将来的に Legacy Architecture を段階的に廃止せざるを得ません。
0.80 では、New Architecture で動作しない API を使用している場合に React Native DevTools に警告が表示されるよう、いくつかの警告を追加しました。これらの警告を無視せず、将来に備えてアプリやライブラリを New Architecture に移行することを推奨します。詳しくは私たちが App.js で発表したトーク「Life After Legacy: The New Architecture Future」をご覧ください。
\
React 19.1.0\
この React Native のリリースには最新の React 安定版 19.1.0 が同梱されています。React 19.1.0 に導入された新機能とバグ修正の全一覧は release description をご確認ください。
警告: React 19.1.0 の注目点の一つに owner stacks の実装と改善があります。これは開発時のみに有効で、どのコンポーネントが特定のエラーの原因であるかを特定するのに役立ちます。ただし、@babel/plugin-transform-function-name Babel プラグインを使用している場合(React Native Babel Preset ではデフォルトで有効)、React Native 上で owner stacks が期待通りに動作しないことが判明しています。この問題については今後の React Native リリースで修正を提供する予定です。
\
実験的 — React Native iOS 依存関係のプリビルド\
React Native の iOS アプリをビルドするとき、初回のネイティブビルドに数分かかる、あるいは古いマシンだとさらに時間がかかることに気づいた方もいると思います。これは React Native iOS のコードとその依存関係をすべてコンパイルする必要があるためです。ここ数週間、Android と類似のアプローチで、初回のビルド時間を短縮するために React Native コアの一部を iOS 用にプリビルドする実験を行ってきました。
React Native 0.80 は、iOS 向けに React Native の一部をプリビルドして提供できる最初のリリースです。リリースプロセス中に、ReactNativeDependencies.xcframework という XCFramework を生成しており、これは React Native が依存するサードパーティ依存ライブラリのみをプリビルドしたものです。私たちのベンチマーク(M4 マシン上)では、プリビルドを利用した場合の iOS ビルドはソースからビルドするより約 12% 高速になりました。
また、ユーザーからのいくつかのバグ報告は React Native のサードパーティ依存関係に関連するビルド問題に起因していました(例: #39568)。サードパーティ依存関係をプリビルドすることで、これらのビルド関連問題を回避できる可能性があります。なお、React Native 全体をプリビルドしているわけではなく、Folly や GLog のように Meta が直接管理していないライブラリのみをプリビルドしています。将来のリリースでは、残りの React Native コアもプリビルドとして提供する予定です。
\
使い方\
この機能はまだ実験的で、デフォルトでは有効になっていません。使用する場合は、以下のようにして pods をインストールします。
RCT_USE_RN_DEP = 1 bundle exec pod install
あるいは、リポジトリ内の全開発者に対して有効にしたい場合は、Podfile を次のように変更できます。
if linkage != nil
Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
use_frameworks! :linkage => linkage.to_sym
end
+ ENV['RCT_USE_RN_DEP'] = '1'
target 'HelloWorld' do
config = use_native_modules!
プリビルドが原因と思われる問題が発生した場合は、この discussion に報告してください。私たちは問題点を調査し、アプリへの影響が透明になるよう努めます。
\
その他の変更\
\
Android — IPO による APK サイズ縮小\
このリリースでは、React Native でビルドしたすべての Android アプリに対してサイズ削減の効果がありました。0.80 からは React Native と Hermes の両方のビルドで Interprocedural Optimization(IPO)を有効化しており、これによりすべての Android アプリで約 1MB の削減が得られます。React Native を 0.80 にアップデートするだけでこのサイズ改善は適用され、プロジェクトに追加の変更は不要です。
\
New App Screen の再設計\
Expo を使用していないが Community CLI & Template を使用している場合、このバージョンでは New App Screen を独立パッケージに移動し、見た目を刷新しました。これにより Community Template で新しいアプリを作成したときの初期ボイラープレートが減り、より大きな画面での表示も改善されます。
\
JSC のコミュニティサポートについての通知\
React Native 0.80 は、ファーストパーティの JSC サポートを提供する最後のバージョンです。JSC のサポートはコミュニティ保守のパッケージ @react-native-community/javascriptcore を通じて提供されます。発表を見逃した場合は、詳細をここで確認できます(Breaking Changes の通知)。
\
Breaking Changes(破壊的変更)\
\
main パッケージに "exports" フィールドを追加\
JS Stable API の変更の一部として、react-native の package.json マニフェストに "exports" フィールドを導入しました。0.80 では、このマッピングはデフォルトであらゆる JavaScript サブパスを引き続き公開しているため大きな破壊的変更にはなっていませんが、react-native パッケージ内のモジュール解決方法に微妙な影響を与える可能性があります。
\
- Metro では、platform-specific 拡張子が "exports" マッチに対して自動展開されない場合があります。このための shim モジュールをいくつか用意しました(#50426)。\
- Jest では、deep imports のモック機能に変更が生じる可能性があり、テストの更新が必要になる場合があります。
\
その他の破壊的変更(概要)\
以下は製品コードに軽微な影響を与える可能性があるその他の変更点です。
\
JS\
- eslint-plugin-react-hooks を v4.6.0 から v5.2.0 に更新しました(フルチェンジログはこちら)。react-hooks の lint ルールが新たなエラーを出す場合があり、それらを修正または抑制する必要があります。
\
Android\
- React Native に同梱される Kotlin のバージョンを 2.1.20 に更新しました。Kotlin 2.1 はプレビューの言語機能を導入しており、モジュール/コンポーネントで利用できます。公式リリースノートを参照してください。\
- StandardCharsets クラスを削除しました(0.73 で非推奨)。代わりに java.nio.charset.StandardCharsets を使用してください。\
- 複数のクラスを internal に変更しました。これらは公開 API の一部ではないためアクセスすべきではありません。影響を受けるライブラリには既に通知またはパッチを提出しています: com.facebook.react.fabric.StateWrapperImpl、com.facebook.react.modules.core.ChoreographerCompat、com.facebook.react.modules.common.ModuleDataCleaner。\
- Java から Kotlin に移行したクラスがあり、引数の nullable 性や型が変更されている場合があるため、利用している場合はコードの調整が必要になるかもしれません。該当箇所の例: com.facebook.react.devsupport 配下の全クラス、com.facebook.react.bridge.ColorPropConverter、com.facebook.react.views.textinput.ReactEditText、com.facebook.react.views.textinput.ReactTextInputManager。
\
iOS\
- RCTUtils.h から RCTFloorPixelValue フィールドを削除しました。RCTFloorPixelValue メソッドは React Native で使用されておらず、完全に削除しました。
さらに小さな破壊的変更は 0.80 の CHANGELOG に記載しています。
\
謝辞\
React Native 0.80 は 127 名の貢献者による 1167 件以上のコミットを含んでいます。皆さんの貢献に感謝します!本リリースで重要な貢献を行ってくださったコミュニティメンバーに特別な感謝を送りたいと思います:
\
- iOS の React Native Dependencies プレビルド作業: Christian Falch\
- Strict TypeScript API 作業: Iwo Plaza、Jakub Piasecki、Dawid Małecki
また、本投稿のドキュメント作成に貢献した方々にも感謝します:Riccardo Cipolleschi(iOS prebuilds 部分)、Alex Hunt(Deep imports 非推奨化・Strict TypeScript API・New App Screen 再設計)、Nicola Corti(Legacy Architecture 凍結と警告)。
\
0.80 へのアップグレード\
既存プロジェクトの React Native バージョン間のコード変更を確認するには、React Native Upgrade Helper と Upgrading ドキュメントを利用してください。新しいプロジェクトを作成する場合は...