📱

MacがなくてもiOS開発ができる!expo-dev-clientについて

2024/12/20に公開

この記事はReact Native 全部俺 Advent Calendar 20目の記事です。

https://adventar.org/calendars/10741

このアドベントカレンダーについて

このアドベントカレンダーは @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が必要になるケース

https://docs.expo.dev/clients/introduction/

アプリ開発を進めていく中で、以下のような状況に遭遇することがあります:

  • アプリで使いたい機能が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を使ったストアへのリリース方法について解説します。

https://docs.expo.dev/build/introduction/

Discussion