久しぶりにReact Nativeでアプリを作りたい!と思った時に、
最近はExpo一択の風潮になっていて、どっちを使うべきなんだろう?と調べた時の記録。
おさらい: React Nativeとは
Facebookが開発したJavaScriptのUIフレームワークである、
Reactを使ってネイティブアプリ (iOS/Android) を作ることができるツール。
ネイティブアプリ上でJavaScriptのランタイム (JavaScriptCore) を動かし、
JavaScriptのコードに対応するネイティブコードを繋げることで動作する仕組みを提供している。
ネイティブを触ることができるので、
公式コンポーネントやサードパーティのライブラリでは実現できない挙動を作りたかったら、
自分でネイティブコードを書いてJavaScriptと対応付けさせるための機能も用意されている。
https://reactnative.dev/docs/native-modules-ios
https://reactnative.dev/docs/native-modules-android
Expoとは何か
ExpoはReact Nativeのビルドや開発を支援してくれるサービス。
React Nativeではネイティブのコードを触ることが出来るので、
逆にXCodeやAndroid StudioといったiOS/Androidの開発環境を構築する必要があった。
Expoは公式に「no need for you to touch Xcode or Android Studio」と書かれているように、
XCodeやAndroid Studioでビルドせずに、JavaScriptだけで実機で動作するようにしてくれる。
編集したJavaScriptのコードがリアルタイムに実機に反映される様子は、感動ものでした。
Expoのメリット
「ネイティブの環境構築にハマらずに進められるので開発速度が向上する」
ことが一番でしょうか。
例えばFirebaseをReact Nativeで使う場合、
① JavaScriptオンリーの公式パッケージを使う (一部機能が利用不可)
② ネイティブSDKをラップしたサードパーティのreact-native-firebaseを使う (フル機能が利用可)
上記の2つの方法があります。
①の公式パッケージだと特にFirebase Analyticsが使えないのがネックで、
react-native-firebaseの導入を検討するのではないでしょうか。
ただネイティブコードを使うパッケージの場合、
XCodeとAndroid Studio両方での設定が必要になります。
React Nativeに慣れていない内はここで数時間ハマることもちらほら。
自分が試した時は、CocoaPodsが古くpod repo update
だけで20分かかってしまいました。
Expoで用意されているAPIを使えば、
ネイティブの環境構築の手間をかけずに開発に集中することができ、
スピードダッシュをかけることができるのが、最大のメリットでしょう。
Expoのデメリット
メリットの反対ですが、「ネイティブのコードを触ることができない」ことです。
上記のFirebase Analyticsのようにネイティブの機能が必要な要件は満たせません。
例えば画像アップロード機能を作りたいと思った時に、
expoが提供しているexpo-image-picker
では画像複数枚を選択することが出来ません。
Allow choosing multiple images in ImagePicker.
こちらの要望には上がってるのですが、対応される気配は無さそうですね...
expo-image-picker-multiple
というパッケージもあるのですが、
スター数が少なく、実際使ってみてもカスタマイズ性が乏しくイマイチでした。
react-native-image-crop-picker
を使えば画像複数枚の要件を満たすことができるのですが、思いっきりネイティブの機能を使っているので、Expoでは利用できません。
公式のAPIドキュメントをみれば分かる通り、提供しているモジュールは非常に豊富なのですが、
Expoでは出来ない要件は、開発スピードとトレードオフで捨てる覚悟が必要になります。
Ejectとは
Expoでネイティブの機能を使いたくなってきたら、
Ejectと呼ばれる作業によってExpo SDKをReact NativeやiOS/Android SDKをラップしている状態から、ひとつのモジュールとして役割を果たす状態に分解することができます。
これにより、ネイティブにアクセスすることが出来るのですが、
Expo Client上では実行ができなくなるのでネイティブでビルドする環境が必要になります。
Expo Bare Workflow?
Expo SDK34から、EjectしたアプリをExpo Client上で動かすことが、Bare Workflowという名称でサポートされるようになりました。
これにより開発中はネイティブのビルドを待たずに、Expo Client上で確認することができます。
ただし、Expo Clientではネイティブのコードは動かないので、
react-native-firebase
等のネイティブモジュールを使っているライブラリを使っている箇所は、*.expo
といった拡張子でExpo用のファイルを用意するといった工夫が必要になります。
またBare Workflowのアプリのリリースビルドに関しては、まだサポートされていないようです。
https://docs.expo.io/bare/exploring-bare-workflow/#releasing-to-app-store-and-play-store
まとめ
Bare Workflowなら良い所どりが出来る気がしていたのですが、
やはりEjectせずに、完全にExpoに乗っかる方が、大きな恩恵を得ることが出来るでしょう。
Expoに乗っかった仕様でアプリを形にし運用してから、
徐々にネイティブに関しても学び、EjectしてBare Workflowへ移行していくという流れが、
アプリ開発に慣れていないWeb系開発者には向いているのではないでしょうか。
ということで結論、これからReact Native始める人はExpoに乗っかっていきましょう!