MacがなくてもiOS開発ができる!expo-dev-clientについて
この記事はReact Native 全部俺 Advent Calendar 20目の記事です。
このアドベントカレンダーについて
このアドベントカレンダーは @itome が全て書いています。
基本的にReact NativeおよびExpoの公式ドキュメントとソースコードを参照しながら書いていきます。誤植や編集依頼はXにお願いします。
Expo Buildは開発用/本番用のバイナリを簡単にビルドできるクラウドサービスです。開発時の基本はExpo Goを使用し、必要に応じてexpo-dev-clientを導入することで、カスタムネイティブコードを含むアプリの開発も可能になります。本番用のビルドはapp.jsonの設定でビルドプロファイルを切り替えて管理でき、ローカルに開発環境を用意する必要がないため、チーム全員が同じ環境でビルドを行えます。
まずはExpo Goから始める
Expoでアプリを開発する時、最初に使うのがExpo Goです。スマートフォンにExpo Goをインストールし、npx create-expo-app
で作成したプロジェクトをnpx expo start
で起動するだけで、すぐにアプリの開発が始められます。React Nativeの知識があれば、特別な環境構築なしにアプリ開発をスタートできます。
Expo Goを使った開発では、コードの変更がリアルタイムで反映され、UIの調整やロジックの実装を効率的に進められます。Expoが提供する様々なAPIも、追加の設定なしですぐに使えます。カメラやプッシュ通知、位置情報など、モバイルアプリでよく使われる機能の多くが、Expo Goの中に組み込まれています。
expo-dev-clientが必要になるケース
アプリ開発を進めていく中で、以下のような状況に遭遇することがあります:
- アプリで使いたい機能がExpo Goに組み込まれていない場合
- 既存のネイティブライブラリを使う必要がある場合
- アプリの起動時にカスタムの初期化処理を入れたい場合
- 特定のデバイスでしか使えない機能を実装したい場合
- プッシュ通知やBluetoothの挙動をカスタマイズしたい場合
このような場合、2つの選択肢があります。1つは従来のようにexpo prebuild
を実行してネイティブプロジェクトを作成し、XcodeやAndroid Studioでローカルビルドする方法です。もう1つはexpo-dev-clientを導入する方法です。
ローカルビルドは完全な自由度が得られる一方で、iOS/Androidそれぞれの開発環境を用意し、ネイティブアプリの開発知識も必要になります。対してexpo-dev-clientは、Expo Goの開発体験を維持しながら、カスタムネイティブコードの実行を可能にします。特にチーム開発においては、開発環境の統一が容易なexpo-dev-clientの導入を検討する価値があります。
基本的な考え方として、できるだけExpo Goで開発を続け、カスタムネイティブコードが必要になった時点でexpo-dev-clientの導入を検討します。ネイティブコードの自由度がより必要な場合や、既存のネイティブアプリのコードベースがある場合は、ローカルビルドを選択するのが適切でしょう。
expo-dev-clientを導入する
では実際にexpo-dev-clientを導入してみましょう:
# パッケージをインストール
$ npx expo install expo-dev-client
# 開発用バイナリをビルド
$ eas build --profile development
# iOSシミュレータ用のビルド
$ eas build --profile development --platform ios
expo-dev-clientを導入しても、開発時の体験はほとんど変わりません。ホットリロードは引き続き使えますし、エラー表示も見やすく、デバッグツールも充実しています。大きな違いは、カスタムネイティブコードが実行できるようになることと、開発用のバイナリを別途ビルドする必要が出てくることです。
EAS Buildでビルドを管理する
ビルドプロファイルの設定
開発やリリースのために、異なる設定のビルドを作り分けることができます。eas.jsonでビルドプロファイルを設定します:
{
"build": {
"development": {
"developmentClient": true,
"distribution": "internal",
"ios": {
"simulator": true,
"resourceClass": "m1-medium"
},
"android": {
"buildType": "apk"
}
},
"preview": {
"distribution": "internal",
"ios": {
"resourceClass": "m1-medium",
"simulator": false
},
"android": {
"buildType": "apk"
}
},
"production": {
"ios": {
"resourceClass": "m1-medium",
"distribution": "store"
},
"android": {
"buildType": "app-bundle"
}
}
}
}
ビルドの実行
# 開発用ビルド(iOSシミュレータ用)
$ eas build --profile development --platform ios
# プレビュービルド(テスト用)
$ eas build --profile preview --platform all
# 本番用ビルド
$ eas build --profile production --platform all
ビルドが始まると、進行状況はWebコンソールで確認できます。エラーが発生した場合も、ログを見ながら原因を特定することができます。
環境変数の管理
開発環境と本番環境で異なる設定を使用する場合は、環境変数を活用します:
// app.config.js
export default {
expo: {
name: process.env.APP_VARIANT === "production"
? "MyApp"
: "MyApp (Dev)",
extra: {
apiKey: process.env.API_KEY,
environment: process.env.APP_VARIANT,
}
},
};
機密情報はEAS Secretsで管理することで、セキュアな運用が可能です:
# プロジェクト全体で使う環境変数を設定
$ eas secret:create
ビルドを効率化するためのポイント
ビルド時間を短縮するために、キャッシュの活用を推奨します:
{
"build": {
"development": {
"cache": {
"key": "developer-v1",
"paths": [
"~/.npm",
"~/.yarn",
"~/Library/Caches/CocoaPods",
"~/.gradle/caches"
]
}
}
}
}
まとめ
Expo Buildとexpo-dev-clientを使うことで、カスタムネイティブコードを含むアプリの開発からリリースまでをスムーズに行うことができます。特に複数の開発者が関わるプロジェクトでは、EASを使うことで環境差異による問題を防ぎ、効率的な開発フローを構築できます。
次回は、EAS Submitを使ったストアへのリリース方法について解説します。
Discussion