ClaudeReact NativeApr 8, 2025, 12:00 AM

React Native 0.79 - Faster tooling and much more

A condensed section focused on the key takeaways first.

Original Post

Quick Digest

Summary

A condensed section focused on the key takeaways first.

claudeenmodel: claude-sonnet-4-20250514

React Native 0.79 - Performance Improvements and Tooling Updates

Key Points

  • Metro startup 3x faster with deferred hashing
  • Android apps start 12% faster with uncompressed JS bundles
  • Remote JS Debugging removed, use React Native DevTools

Summary

React Native 0.79 delivers significant performance improvements across development and runtime environments, along with important architectural changes and breaking updates.

Key Points

Performance Improvements

  • Metro 0.82: 3x faster startup with deferred hashing, especially beneficial for large projects and monorepos
  • Android startup optimization: JavaScript bundles now ship uncompressed by default, reducing time-to-interactive by up to 12% (400ms improvement tested on Discord app)
  • Package exports: Stable support for package.json "exports" and "imports" fields for better npm compatibility

Architecture Changes

  • JSC community migration: JavaScriptCore engine moving to @react-native-community/javascriptcore package
  • iOS Native Modules: New Swift-compatible registration system using package.json configuration
  • Module exports modernization: 46 internal APIs updated to use ES6 export syntax

Breaking Changes

  • Remote JS Debugging removed: Use React Native DevTools instead of legacy Chrome debugging
  • Package exports enabled by default: May cause compatibility issues with Firebase, AWS Amplify (workaround: set resolver.unstable_enablePackageExports = false)
  • CSS compliance: Stricter validation for box-shadow, filter properties, and hwb() color syntax
  • Import syntax changes: Deep imports from react-native internals require syntax updates

Configuration Options

  • Android bundle compression can be controlled via enableBundleCompression in app/build.gradle
  • Root imports from 'react-native' strongly recommended to avoid future breaking changes

Full Translation

Translations

A translation section that keeps the flow of the original article.

claudejamodel: claude-sonnet-4-20250514

React Native 0.79 - より高速なツールと多くの改善

本日、React Native 0.79のリリースを発表できることを嬉しく思います!このリリースでは、様々な面でのパフォーマンス改善と複数のバグ修正が含まれています。まず、Metroは遅延ハッシュ化により起動が高速化され、package exportsの安定サポートが追加されました。また、JSバンドル圧縮の変更などにより、Androidでの起動時間も改善されます。

ハイライト

  • 新しいMetro機能
  • JSCのコミュニティパッケージへの移行
  • iOS: Swift互換のNative Modules登録
  • Android: より高速なアプリ起動
  • Remote JS Debuggingの削除

ハイライト

Metro: より高速な起動とpackage exportsサポート

このリリースにはMetro 0.82が含まれています。このバージョンでは遅延ハッシュ化を使用して、初回のyarn startの速度を通常3倍以上改善し(大規模プロジェクトやmonoreposではさらに高速化)、日常的な開発体験とCIビルドを高速化します。

また、Metro 0.82では、package.jsonの"exports"と"imports"フィールド解決を安定版に昇格させています。"exports"解決はReact Native 0.72で導入され、"imports"サポートはコミュニティ貢献で追加されました。両方ともReact Native 0.79のすべてのプロジェクトでデフォルトで有効になります。これにより、モダンなnpm依存関係との互換性が向上し、プロジェクトを整理するための新しい標準準拠の方法が開かれます。

破壊的変更

package.json "exports"をコミュニティでしばらくテストしてきましたが、この切り替えは特定のパッケージやプロジェクト設定で破壊的変更となる可能性があります。特に、FirebaseやAWS Amplifyなどの人気パッケージでユーザーから報告された非互換性を認識しており、ソースでの修正に取り組んでいます。

問題が発生している場合:

  • Metro 0.81.5 hotfixに更新するか、resolver.unstable_enablePackageExports = falseを設定してオプトアウトしてください
  • 影響を受けるパッケージと今後の更新については、expo/expo#36551を参照してください

JSCのコミュニティパッケージへの移行

React NativeのAPIサーフェスを削減する取り組みの一環として、JavaScriptCore(JSC)エンジンをコミュニティ維持のパッケージに移行しています:@react-native-community/javascriptcore

この変更は、Hermesを使用しているユーザーには影響しません。React Native 0.79以降、readmeのインストール手順に従ってコミュニティサポート版のJSCを使用できます。

React Nativeコアが提供するJSCバージョンは0.79でも利用可能ですが、近い将来削除する予定です。JSCをコミュニティ維持のパッケージに移行することで、JSCバージョンをより頻繁に更新し、最新機能を提供できるようになります。コミュニティ維持のJSCは、React Nativeとは別のリリーススケジュールに従います。

iOS: Swift互換のNative Modules登録

このリリースでは、Native ModuleをReact Nativeランタイムに登録する方法を刷新しています。新しいアプローチは、公式ドキュメントで説明されているコンポーネントと同じアプローチに従います。

このバージョンのReact Nativeから、package.jsonファイルを変更してモジュールを登録できます。iosプロパティに新しいmodulesProviderフィールドを導入しました:

"codegenConfig": {
  "ios": {
+   "modulesProvider": {
+     "JS Name for the module": "ObjC Module provider for the pure C++ TM or a class conforming to RCTTurboModule"
+   }
  }
}

Codegenがpackage.jsonファイルから関連するすべてのコードを作成します。純粋なC++ Native Moduleを使用する場合は、この推奨設定に従う必要があります:

アプリで純粋なC++ Native Modulesを設定する

純粋なC++ Native Modulesの場合、C++ Native Moduleとアプリの残りの部分を接続する新しいObjectiveC++クラスを追加する必要があります:

CppNativeModuleProvider.h

#import <Foundation/Foundation.h>
#import <ReactCommon/RCTTurboModule.h>

NS_ASSUME_NONNULL_BEGIN

@interface YourNativeModuleProvider : NSObject<RCTModuleProvider>

@end

NS_ASSUME_NONNULL_END

CppNativeModuleProvider.mm

#import "Provider.h"
#import <ReactCommon/CallInvoker.h>
#import <ReactCommon/TurboModule.h>
#import ".h"

@implementation NativeSampleModuleProvider

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params {
  return std::make_shared<facebook::react::NativeSampleModule>(params.jsInvoker);
}

@end

この新しいアプローチにより、アプリ開発者とライブラリメンテナーの両方でNative Modulesの登録を統一しました。ライブラリはpackage.jsonで同じプロパティを指定でき、Codegenが残りを処理します。

このアプローチは、SwiftのAppDelegateで純粋なC++ Native Moduleの登録を妨げていた0.77で導入した制限を解決します。ご覧のとおり、これらの変更はAppDelegateを変更せず、生成されたコードはSwiftとObjective-Cの両方で実装されたAppDelegateで動作します。

Android: より高速なアプリ起動

Androidの起動時間を大幅に改善する変更も提供しています。このバージョンから、APK内のJavaScriptバンドルを圧縮しなくなります。

以前は、Androidシステムがアプリを起動する前にJavaScriptバンドルを展開する必要がありました。これがアプリ起動時の大幅な遅延を引き起こしていました。このリリースから、JavaScriptバンドルをデフォルトで非圧縮で配布するため、Androidアプリは一般的により高速に起動します。

MargeloチームがDiscordアプリでこの機能をテストし、大幅なパフォーマンス向上を得ました:Discordのtime-to-interactive(TTI)が400ms短縮され、1行の変更で12%の高速化を実現しました(Samsung A14でテスト)。

一方、バンドルを非圧縮で保存すると、ユーザーデバイスでのアプリケーションの容量消費が増加します。これが懸念される場合は、app/build.gradleファイルのenableBundleCompressionプロパティを使用してこの動作を切り替えることができます。

app/build.gradle

react {
    // ...
    // JSバンドルを圧縮したい場合(起動が遅く、容量消費が少ない)
    enableBundleCompression = true
    // JSバンドルを圧縮したくない場合(起動が速く、容量消費が多い)
    enableBundleCompression = false
    // デフォルトは `false`
}

このリリースではAPKサイズが増加しますが、APKはネットワークからダウンロード時に圧縮されるため、ユーザーはAPKダウンロードサイズで追加コストを支払うことはありません。

破壊的変更

Remote JS Debuggingの削除

デバッグ改善の継続的な取り組みの一環として、Chrome経由のRemote JS Debuggingを削除しています。このレガシーデバッグ方法はReact Native 0.73で非推奨となり、ランタイムオプトインに移行されました。

モダンで信頼性の高いデバッグには、React Native DevToolsを使用してください。これは、React Nativeがreact-native-debuggerコミュニティプロジェクトと互換性がなくなることも意味します。

Redux DevToolsなどのサードパーティデバッグ拡張機能を使用したい開発者には、Expo DevTools Pluginsまたはこれらのツールのスタンドアロン版の統合をお勧めします。

詳細は専用の投稿をお読みください。

内部モジュールのexport構文への更新

JavaScriptコードベースの近代化の一環として、react-native内の多数の実装モジュールをmodule.exportsの代わりにexport構文を一貫して使用するように更新しました。合計約46のAPIを更新しており、詳細はchangelogで確認できます。

この変更は既存のimportに微妙な影響を与えます:

ケース1: デフォルトエクスポート

// 変更 - require()構文
- const ImageBackground = require('react-native/Libraries/Image/ImageBackground');
+ const ImageBackground = require('react-native/Libraries/Image/ImageBackground').default;

// 変更なし - import構文
import ImageBackground from 'react-native/Libraries/Image/ImageBackground';

// 推奨 - ルートimport
import {ImageBackground} from 'react-native';

ケース2: セカンダリエクスポート このパターンのケースは非常に少なく、ルートの'react-native' importを使用する場合は影響を受けません。

// 変更なし - require()構文
const BlobRegistry = require('react-native/Libraries/Blob/BlobRegistry');

// 変更なし - 分割代入でのrequire()構文
const {register, unregister} = require('react-native/Libraries/Blob/BlobRegistry');

// 変更 - 単一オブジェクトとしてのimport構文
- import BlobRegistry from 'react-native/Libraries/Blob/BlobRegistry';
+ import * as BlobRegistry from 'react-native/Libraries/Blob/BlobRegistry';

// 変更なし - 分割代入でのimport構文
import {register, unregister} from 'react-native/Libraries/Blob/BlobRegistry';

// 推奨 - ルートimport
import {BlobRegistry} from 'react-native';

この変更の影響は、特にTypeScriptで書かれ、import構文を使用するプロジェクトでは極めて限定的であると予想されます。コードを更新するために型エラーをチェックしてください。

ヒント:ルートのreact-native importを強く推奨

一般的な要点として、将来の余分な破壊的変更を避けるため、ルートの'react-native'パスからのimportを強く推奨します。次のリリースでは、React NativeのパブリックJavaScript APIをより適切に定義する一環として、深いimportを非推奨にする予定です(RFCを参照)。

その他の破壊的変更

このリストには、製品コードに軽微な影響を与える可能性があり、注目に値するその他の破壊的変更が含まれています。

  • box shadowsとfiltersでの無効な単位なし長さ: React NativeをCSS/Web仕様により準拠させるため、box-shadowfilterで単位なし長さをサポートしなくなりました。1 1 blackのbox-shadowを使用していた場合、レンダリングされません。代わりに1px 1px blackのような単位を指定してください。

  • normalize-colorから不正なhwb()構文サポートを削除: React NativeをCSS/Web仕様により準拠させるため、hwb()の無効な構文を制限しました。従来React Nativeはカンマ区切りの値(例:hwb(0, 0%, 100%))をサポートしていましたが、これをサポートしなくなりました(hwb(0 0% 100%)に移行してください)。この変更の詳細はこちらをお読みください。

  • Libraries/Core/ExceptionsManagerのエクスポート更新: React Native JS APIの近代化の取り組みの一環として、ExceptionsManagerを更新し、デフォルトのExceptionsManagerオブジェクトとSyntheticErrorをセカンダリエクスポートとしてエクスポートするようになりました。

謝辞

React Native 0.79には100人の貢献者による944以上のコミットが含まれています。すべてのハードワークに感謝します!

このリリースで重要な貢献を提供したコミュニティメンバーに感謝を送りたいと思います:

  • Marc Rousavy氏:「Android: より高速なアプリ起動」機能の開発と文書化
  • Kudo Chien氏とOskar Kwaśniewski氏:@react-native-community/javascriptcoreパッケージの作業と「JSCのコミュニティパッケージへの移行」セクションの執筆
  • James Lawson氏:Metroでのimport subpath解決サポートの追加

さらに、このリリース投稿の機能文書化に取り組んだ追加の著者にも感謝します:

  • Rob Hogan氏:「新しいMetro機能」セクション
  • Alex Hunt氏:「Remote JS Debuggingの削除」と「内部モジュールのexport構文への更新」セクション
  • Riccardo Cipolleschi氏:iOS Native Module登録の作業

0.79へのアップグレード

既存のプロジェクトについては、アップグレードドキュメントに加えて、React Native Upgrade Helperを使用してReact Nativeバージョン間のコード変更を確認してください。

新しいプロジェクトを作成するには:

npx @react-native-community/cli@latest init MyProject --version latest

Expoを使用している場合、React Native 0.79は今後のExpo SDK 53でReact Nativeのデフォルトバージョンとしてサポートされます。

情報

0.79は現在React Nativeの最新安定版であり、0.76.xはサポート対象外に移行します。詳細については、React Nativeのサポートポリシーを参照してください。近い将来、0.76の最終的なend-of-lifeアップデートを公開する予定です。