EAS でビルド・配布

EAS(Expo Application Services)は Expo 公式のクラウドビルド/配布サービス。 eas build で iOS/Android をビルド、eas submit でストア提出、eas update で OTA。 ローカルに Xcode / Android Studio が無くても本格配信ができる。

3 つの主要サービス

全部使うのが一般的だが、ビルドだけ EAS / 提出は手動、のような部分利用も可能。

準備

npm install -g eas-cli
eas login
eas build:configure   # eas.json を作る

無料枠でも個人利用なら十分。チームや高頻度ビルドは有料プラン。

eas.json

ビルド設定。profile(development / preview / production)ごとに振る舞いを変える。

eas.json(標準的な3プロファイル)
{
  "cli": { "version": ">= 14.0.0" },
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal",
      "channel": "development"
    },
    "preview": {
      "distribution": "internal",
      "channel": "preview"
    },
    "production": {
      "channel": "production",
      "autoIncrement": true
    }
  },
  "submit": {
    "production": {
      "ios":     { "appleId": "you@example.com", "ascAppId": "1234567890", "appleTeamId": "ABCD12345" },
      "android": { "serviceAccountKeyPath": "./pc-api.json", "track": "production" }
    }
  }
}

3 つのプロファイルの意味

Dev Build(開発用)

Expo Go の自前バージョン。プロジェクト固有のネイティブモジュールを含む開発専用アプリ。

eas build --profile development --platform ios
eas build --profile development --platform android
# 両方
eas build --profile development --platform all

ビルドが終わるとQR コード/URLが出る。それを実機で開いてインストール → アプリを起動して Metro と接続。

iOS シミュレータ用

通常の iOS ビルドは実機向け(署名付き .ipa)。シミュレータには別途:

eas build --profile development-simulator --platform ios

# eas.json 側で
{
  "build": {
    "development-simulator": {
      "developmentClient": true,
      "distribution": "internal",
      "ios": { "simulator": true }
    }
  }
}

Production ビルド

eas build --profile production --platform ios
eas build --profile production --platform android

初回は署名・キーストアの管理が走る:

ローカルビルド

クラウドではなく自機でビルドしたい時:

eas build --profile production --platform ios --local
eas build --profile production --platform android --local

ローカル Xcode / Android SDK が必要。Mac の Apple Silicon ならそこまで遅くない。 無料枠を超えそうな大量ビルドの時に有用。

EAS Submit(ストア提出)

eas submit --profile production --platform ios
eas submit --profile production --platform android

iOS(App Store Connect)

Android(Google Play Console)

EAS Update(OTA 更新)

JS バンドル + アセットだけを差分配信。再ビルドや審査なしでバグ修正・小さい機能を出せる。

セットアップ

npx expo install expo-updates
eas update:configure

更新を発行

eas update --channel production --message "fix login bug"

上のコマンドでアップロードすると、channel: production でビルドされたアプリ群が次回起動時に新しい JS を取得する。

自動チェック

起動時に自動で更新確認するのが既定。手動制御もできる:

import * as Updates from "expo-updates"

async function checkForUpdate() {
  const result = await Updates.checkForUpdateAsync()
  if (result.isAvailable) {
    await Updates.fetchUpdateAsync()
    await Updates.reloadAsync()
  }
}

OTA でできないこと

app.json と Continuous Native Generation (CNG)

Expo はネイティブプロジェクトを自動生成する仕組みを持つ。ios/android/ ディレクトリは app.json + plugins + package.json から都度生成される(npx expo prebuild)。

メリット:

どうしても直接 ios/ をいじりたい時は npx expo prebuild 後に手で書く運用("bare workflow" 相当)も可能。

環境変数とシークレット

ローカル

.env 系。Expo は EXPO_PUBLIC_ プリフィックス付きの変数だけ JS バンドルに含める(クライアントに渡す)。

EXPO_PUBLIC_API_URL=https://api.example.com
SECRET_API_KEY=...   # クライアントには出ない(が、サーバ側でしか使えない)

EAS でのビルド時シークレット

eas secret:create --scope project --name SENTRY_AUTH_TOKEN --value "xxx"
eas secret:list

本番ビルド中に環境変数として展開される。Apple App Connect のシークレットや Sentry の auth token等を入れる。

バージョン管理

テスト配布

iOS — TestFlight

Android — Google Play 内部テスト

EAS の Internal Distribution

ストアを介さずにQR コードで配布。社内テスト用。

{
  "build": {
    "preview": {
      "distribution": "internal"
    }
  }
}

iOS は ad-hoc 署名(最大 100 デバイス)になる。

CI / CD 連携

GitHub Actions など CI から自動ビルドする場合:

Expo 公式に GitHub Actions のテンプレートあり。

典型的なリリースフロー

  1. 機能ブランチで開発、Dev Build で実機確認
  2. main に PR、CI でpreview ビルドを作成 → 内部レビュー
  3. main にマージ、production ビルドを作成
  4. eas submit で TestFlight / Play 内部テストへ
  5. テスター確認 → ストア審査提出
  6. 承認 → ストア公開
  7. 運用中はバグを EAS Update(OTA)で配信、機能追加は次の production ビルドへ
よくあるトラブル

- iOS 署名エラー: eas credentials でやり直す
- Android Keystore 紛失: アプリの更新が出せなくなる。必ずバックアップか EAS で管理
- 古い SDK でのビルド失敗: Xcode の最新版を要求されることがある
- ストア審査リジェクト: パーミッション文言が空・カメラ用途が不明・暗号化申告漏れが頻発

参考

公式ドキュメント: EAS Build / EAS Submit / EAS Update