はじめに
毎年恒例の State of JavaScript や JavaScript Rising Stars を眺めていて、モバイル部門にて2023,24年で2連覇している Expo が気になったので、クロスプラットフォーム開発の今を知るべく、まとめてみました。なぜ注目されているのか、その導入効果をみていきます。
ポイントは オンボーディングの手軽さ × 手厚い開発・配布サポート機能 です。
※ただし、注意点あり...
Expo
Expoは、React Nativeベースのクロスプラットフォームアプリ開発向けフレームワークです。
主な特徴は、React Nativeとの比較によって語ることができます。
素でReact Nativeを利用する場合の煩わしいポイントとして、以下があります。
- 開発環境(Xcode / Android Studio)のセットアップコストが大きい
- アプリケーションのビルド管理や署名/証明書管理がつらい
- JSの修正反映には、ストア再申請が必要
- OS(iOS / Android)依存となるAPI差分の考慮が必須に近い
また特にExpoがもつ大きな特徴としては、
↓公式の言葉にある通り、クラウドサービス を備えていることが挙げられます。
Expo is a full-stack React Native framework with powerful cloud services to help you move faster at every stage of the app lifecycle.
それではExpoの導入効果を、特徴に準えてみていきたいと思います。
Expo 導入効果
1. 開発体験(DX)の一体設計
React Nativeで求められる開発環境
まずReact Nativeの場合、開発環境として以下を最低限揃える必要があります。
- IDE:VSCode, WebStormなど
- JavaScriptランタイム:Node.js, Bunなど
- iOS開発環境:Xcode, macOS
- Android開発環境:Android Studio ※OS不問
特に iOS / Android 開発環境は、それぞれ用意しなければネイティブビルドできず、iOS Simulator(Xcode同梱)がなければ、macOS以外ではローカル環境における動作検証もできません。
またiOSネイティブビルド(厳密には、App Store Connect へのアップロード)の際には、証明書や署名、アカウント管理が必要不可欠であり、これらは開発体験として大きな運用負荷となりやすいです。
以上から、開発環境構築コストの高さが開発ハードルを上げていると感じます。
Expo で求められる開発環境
では、Expo の場合はどうでしょうか。最低限必要な開発環境は、以下です。
- IDE:VSCode, WebStormなど
- JavaScriptランタイム:Node.js, Bunなど
-
iOS開発環境:Xcode, macOS→ 必須でない1 -
Android開発環境:Android Studio ※OS不問→ 必須でない
Expo は React Native をベースとすることから、開発言語は同じく TypeScript です。なので開発環境は、JavaScriptランタイムとして Node.js や Bun があれば、開発を進めることができます。
よって大きなポイントは、動作検証 と ネイティブビルド + Storeアップロード をどうするか です。
まず 動作検証 ですが、Expo が提供するネイティブアプリ Expo Go が利用できます。これはビルド済のアプリケーション(Expo Go)に対して、ローカルPCで開発したJS BundleをNW経由で配信することで、ネイティブビルドの代替手段として、実機検証ができる仕組みです。なんとQRコードひとつ読みこむだけで、実機確認ができます。
そしてStoreアップロード は、EASを利用することで省力化することができます。
EAS(Expo Application Service)
EASは、Expoが提供するクラウドサービスで、ビルドやアプリストア(App StoreやGoogle Play Store)アップロードをサポートしてくれます。
具体的には、開発者は以下のコマンドひとつで、EASが用意するCI/CDパイプラインが稼働し、ビルドからStoreアップロードまで一連で実施してくれます。
eas build --platform [ios] / [android] --auto-submit
他にもOTAアップデート(詳細は後述)やホスティング機能2を備えており、
至れり尽くせりです。
【 💸 コストに注意 】
Freeプランであれば、追加コストは発生しませんが、ビルド優先度やビルドクレジット、OTAアップデートで配信できるデフォルトの月間アクティブユーザ数(超えた場合は従量課金)など、プランによってコストが異なるため、アプリケーション規模に合わせてプラン選択する必要があります。詳細はPricingを参照ください。
https://expo.dev/pricing
2. OTA(Over-The-Air)アップデートの仕組みが標準組み込み
通常、ネイティブアプリを更新する際は、以下の手順が必要であり
変更 → ビルド → App Store / Google Play 審査 → アプリ更新(ユーザ)
たとえ軽微なUI修正であっても「ネイティブバイナリの変更 = 配布物の変更」のため、このサイクルを繰り返す必要があります。
そこでOTAアップデートは、ネイティブバイナリ(Storeから配信されるアプリ)をそのままに、JavaScript Bundleや静的アセットをアプリ起動のタイミングで差し替えることで、UI/UXを更新することができます。
EASは、そのJS Bundleや静的アセットの管理・配信機能(CDN)を備えています。
Expo は EAS を利用することで、OTAアップデートがサポートされるため、リリースサイクルの最適化を狙うことができます。
React Native 単体では、OTAアップデート機能はなく、自前構築が必要です。
【 🚨 ポリシーを遵守すること 】
OTAはUI調整や軽微な(バグ調整含む)を主とすべきで、新機能追加や審査回避のために利用してはいけません。必ずポリシー準拠のもと、Store更新をしましょう。
3. ネイティブ差分を吸収する独自API
React Native では、ネイティブAPIを直接的に公開する設計を採用しているため、同一機能であっても iOS / Android の OS 仕様差が実装レベルで現れます。なので、権限取得やファイルアクセス、デバイス制御等、OS固有の挙動差を理解した上で、分岐処理や設定管理を行う必要があります。
一例として、「カメラ+権限」について考えます。
Androidはカメラ権限のリクエストが必須のため、下記のようなOS固有実装が発生します。
import { Platform, PermissionsAndroid } from 'react-native';
if (Platform.OS === 'android') {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.CAMERA
);
if (granted !== PermissionsAndroid.RESULTS.GRANTED) {
throw new Error('Camera permission denied');
}
}
// iOSは Info.plist(メタデータ) に書いてある前提で何もしない
では、Expoによる実装です。
この実装の裏では、iOSメタデータ反映やAndroid権限追加が行われています。
import { Camera } from 'expo-camera';
const requestPermission = async () => {
// カメラ権限の状態を取得し、必要ならリクエストする
const { status } = await Camera.requestCameraPermissionsAsync();
if (status !== 'granted') {
alert('カメラ権限が拒否されました');
return;
}
// 権限がある場合の処理
};
またOS差分だけでなく、バージョン違いによるIF差異をSDK側で吸収してくれることで、アプリコード内で明示的な分岐を肩代わりしてくれます。当然ながら新OS対応はExpo SDKのアップデートでよく、アプリコードの変更は原則発生しません。
このように Expo SDK を用いることで、ネイティブ差分を吸収することができます。
注意点
ここまでExpoの導入効果として、開発者体験を主軸に、EASが提供するCI/CDやCDN、OTAアップデート基盤や、SDKとしてExpo本体がもつ有用性を述べてきました。
しかし、システム/プロジェクト特性によっては、一部叶わない可能性があります。
EASはクラウドサービスとして、CI/CDやCDN、OTAアップデート基盤を提供するため、素直に機能に乗っかると、ビルド以降を任せる形となるため、監査観点(誰が・どこで・どうビルドしたか、どこで管理)や障害責任観点、契約等が満たせないという、つまり責任分界によって 要求されるSLAを保証できない可能性がある ため、業界・システム特性を考慮した上で、利用するサービス/機能の選定が必要です。
業務/機能要件から、実装対象をExpo SDKでどのように実現するかを考慮するとともに、
開発・配布基盤として、EASを利用する余地があるかを検討しなければなりません。
おわりに
今話題のExpoについて、クロスプラットフォーム開発のデファクトスタンダードたる可能性をみてみました。紙幅の都合上、具体的な実装方法には触れられていないので、環境構築から開発、アプリリリースまでいずれご紹介できればと思います。
技術選定は、技術そのものの発展度合いに加えて、オンボーディングに直結するという点から、開発体験の重要性を改めて感じました。これからも注目していきたいと思います。
ここまでご覧いただきありがとうございました。
素敵なクリスマス🎄、そして良いお年をお迎えください。
-
機種やOSのバージョン違い等、実機の用意が現実的でないとき、Simulatorによる動作検証を行いたいですが、その際は合ったOSが必要(特にiOSの場合は、macOS)となるため、必須でないと表現しました。 ↩
-
Webアプリの静的サイトホスティングに加え、Next.jsのApp Routerに似た「Expo Router」を備えており、ファイルベースルーティングを実現することが可能です。
https://docs.expo.dev/router/introduction/ ↩