Expo: EAS Build
Expo の有料プランで利用できる EAS を試す。
現時点での制限
まだプレビュー版のため、以下の制限がある (Limitations - Expo Documentation)
- Expo SDK 41 以降の Managed Workflow のみ対応
- CocoaPods はキャッシュされない
-
node_modules
以下もキャッシュされない- ただし、npm cache server がいるため、ダウンロードは早い(はず)[1]
- yarn v1 だとデフォルトで無効になっている
- ビルド時間は 60 分まで
EAS CLI
EAS のための CLI が必要なのでインストールする
$ npm install -g eas-cli
新しいプロジェクトを作成
新規でプロジェクトを作成して試す
$ expo init --npm
EAS を設定する
$ eas build:configure
ウィザード形式で進む
✔ Which platforms would you like to configure for EAS Build? › All
Android の Application-ID と、iOS の Bundle Identifier を決める。使える文字が微妙に異なるので注意...
✔ What would you like your Android application id to be? … com.example.eas_playground
✔ What would you like your iOS bundle identifier to be? … com.example.eas-playground
最後に git commit してもらって終了
iOS シミュレータ向けにビルド
eas.json にシミュレータ用のプロファイルを追加
{
"builds": {
"android": {
"release": {
"workflow": "managed"
}
},
"ios": {
"release": {
"workflow": "managed"
},
"simulator": {
"workflow": "managed",
"distribution": "simulator"
}
}
}
}
eas コマンドでビルドする。
$ eas build --platform ios --profile simulator
✔ Created @my-org/eas-playground on Expo
Warning! Your git working tree is dirty.
This operation needs to be run on a clean working tree, please commit all your changes before proceeding.
✔ Commit changes to git? … yes
✔ Commit message: … Simulator profile
✔ Uploaded to EAS 3s
Build details: https://expo.io/accounts/...
Waiting for build to complete. You can press Ctrl+C to exit.
⠸ Build queued...
Expo.io を覗いてみると進行状況が出ている。
ビルドが完了すると .tag.gz
をダウンロードでき、解凍した .app ファイルをシミュレータにドラッグ&ドロップするとインストールできる。
EAS build の裏側では fastlane を使っているっぽい?
EAS build で iOS をビルドしていると、fastlane で以下のエラーに遭遇した。
❌ error: File /Users/expo/workingdir/build/ios/build/Build/Products/Release-iphonesimulator/myapp.app/main.jsbundle does not exist. This must be a bug with
❌ Metro encountered an error:
Error loading Metro config and Expo app config: Expected `fromDir` to be of type `string`, got `undefined`
Make sure your project is configured properly and your app.json / app.config.js is valid.
If you are using environment variables in app.config.js, verify that you have set them in your EAS Build profile configuration or secrets.
› Generating debug myapp » myapp.app.dSYM
⚠️ Pods/boost-for-react-native: iOS@8.0 deployment version mismatch, expected >= 9.0 <= 14.4.99
▸ ** BUILD FAILED **
▸ The following build commands failed:
▸ PhaseScriptExecution Bundle\ React\ Native\ code\ and\ images /Users/expo/workingdir/build/ios/build/Build/Intermediates.noindex/myapp.build/Release-iphonesimulator/myapp.build/Script-00DD1BFF1BD5951E006B06BC.sh
▸ (1 failure)
** BUILD FAILED **
The following build commands failed:
PhaseScriptExecution Bundle\ React\ Native\ code\ and\ images /Users/expo/workingdir/build/ios/build/Build/Intermediates.noindex/myapp.build/Release-iphonesimulator/myapp.build/Script-00DD1BFF1BD5951E006B06BC.sh
(1 failure)
Exit status: 65
を参考に、プロジェクトのルートに index.js を配置することで解決した。
しかし、iOS/Android いずれも起動時にクラッシュ... 😞
開発中のアプリでは、EAS build は通るものの、デバイスにインストールしたアプリは起動時にクラッシュしてしまった。新規に作ったアプリで、Android に "internal" distribution のプロファイルを追加してビルドしてみる。
{
"builds": {
"android": {
"release": {
"workflow": "managed"
},
"preview": {
"distribution": "internal",
"workflow": "managed",
"buildType": "apk"
}
...
}
ビルド
$ eas build --platform android --profile preview
ビルドが完了すると、コンソールに QR コードが表示されるので、Android の標準カメラ > モード > レンズで読み取る。
何も問題なく動いた。
別のアプリで試したところ問題なく動いたが、画像リソースの一部が抜けてしまう...
とても参考になる投稿をありがとうございます。
私も現在eas builを試しています。
ちょうどiosのeas buildしたアプリでローカルの画像が表示されないバグに直面しているのですが、もし解決していましたらご教示願いたいです。
残念ながらまだ未解決です。今はこのへんガンガン手が入ってそうですし、Expo の Issues をときどき眺めながら気長に待つつもりです。(現状 build:ios/android でも大変満足しています)
返信ありがとうございます。
調査を進めたところ、私の場合はeas buildの問題ではなく、expoをejectした際にmetro.config.jsが書き換わらなかったことに問題があったようです。以下を参考にmetro.config.jsを修正して表示されるようになりましたので一応共有させていただきます。ありがとうございました。
わざわざありがとうございます!
eject はしていないので別問題っぽいですね。なんにせよ解決したようで何よりです。
Expo SDK 41-42
"eject" せずにネイティブコードを扱えるようになる?
- Introducing: Expo Run Commands. Expo Go can get you from zero to “hello… | by Evan Bacon | May, 2021 | Exposition
-
Expo SDK 42 beta is now available | by Brent Vatne | Jun, 2021 | Exposition
- React Native 0.63. これは Expo 40 から変わらない。Expo 43 で新しくなる
-
Hermes on Android -
expo build
以外で実験的に有効になる - EAS build と
expo build
の差異が少なくなった - Stripe のサポート
@stripe/stripe-react-native
- MaskedView の別バージョンのものが追加された
- プッシュ通知の強化
- バックグランドでの通知の処理
- カスタムのサウンド (EAS build のみ)
SDK 42 になったからか、eas.json で使えるキーとかが変わってる。workflow
はなくなった?
Expo managed workflow in 2021. Part 1: The preset Expo runtime | by Brent Vatne | Exposition
- Managed workflow のランタイムは Expo Go に含まれている
-
build:ios
やbuild:android
で使われるビルドツールは "Turtle" と呼ばれている- あらかじめビルドされた "shell" アプリにランタイムとアプリのパッケージを含めてビルドするから
- ビルドコマンドが実行されると、JavaScript バンドル、manifest ファイル、アセットがアップロードされる
- Turtle は新しいワーカーを走らせ、アップロードされたファイルをダウンロードする
- ダウンロードした JavaScript ファイルとアセットを、ランタイムを含んだ "shell" アプリにコピーする
- 最後にユーザーの証明書で署名する
- Managed workflow で作られたアプリは OTA で安全に更新できる
- なぜなら、中身はただの JavaScript ファイルなので、新しいバンドルをダウンロードしてきて入れ替えるだけ。
- しかし、この方式にはいくつかの制限がある
- 特に多い要望である以下のことができない
- Expo SDK に含まれないネイティブライブラリを利用したい
- 使われていないライブラリを含めないことでサイズ削減したい
- オリジナルのネイティブコードを含めたい
- これらを実現するには、ランタイムをカスタマイズ可能にしなくてはいけない
- パート2へ続く
Expo managed workflow in 2021. Part 2: Customizing the runtime | by Brent Vatne | Exposition
- ランタイムをカスタマイズするためには、これまで
expo eject
して Bare workflow に移行するか、最初から Bare workflow で初期化する必要があった。 - Managed workflow でランタイムをカスタマイズできるようにすれば、Managed workflow を諦めずにネイティブコードの追加・削除ができる
- スタンドアロンアプリ
- あらゆるネイティブコードをビルドするためのクラウドサービスが必要だったので、EAS build を作った
-
eas build
を実行すると、リポジトリのコードを clone してアップロードする - EAS build は新しい VM を起動し、ダウンロードしたコードを fastlane または Gradle でビルドする
- 最後にユーザーの証明書で署名する
-
eject
に似たコマンドとしてprebuild
を用意した。これは Manged workflow のプロジェクトからネイティブの iOS/Android プロジェクトを生成する。- EAS build は
prebuild
で生成されたプロジェクトをビルドする。"shell" アプリは必要ない
- EAS build は
-
prebuild
コマンドは不要なライブラリをリンクしないので、アプリのサイズ削減になる。 - ネイティブライブラリの追加
- リンクだけであれば、React Native が自動でやってくれる
- なんらかのセットアップが必要な場合、Expo ライブラリのみ EAS build が自動でやってくれる
- 開発者は Config plugin によって、prebuild プロセス中にセットアップできる
- これで、EAS build でビルドされたアプリではランタイムをカスタマイズできるようになった。
- SDK 41 ではここまで
- Expo Go による開発時には利用できない
- OTA アップデート
- ランタイムに互換性がなければどうするのか。新しい問題
- EAS Update というサービスで解決しようとしている
- 開発時
- 開発時にランタイムをカスタマイズできるようにするために "Expo Development Client" を用意した。
- Expo Go と同じ使い勝手を提供する React Native のライブラリ
- デバッグビルド時には Development Client を使うことができる。リリース時にはこれらのコードは含まれない。
- Development Client を一度ビルドしてしまえば、あとは JavaScript コードに集中できる。
- Development Client は ad-hoc provisioning で配布でき、ブラウザ経由でインストール可能
- 開発時にランタイムをカスタマイズできるようにするために "Expo Development Client" を用意した。
Expo の Development Client を試す
$ expo init my-expo-dev-client --npm
$ cd my-expo-dev-client
$ npm i expo-dev-client
より分かりやすいエラー表示のために App.tsx に import "expo-dev-client"
を追加
import "expo-dev-client";
...
EAS の設定
Development Client で開発するときは EAS Build を使うのが推奨みたいなので設定をする。
まずは EAS CLI のインストール
$ npm install -g eas-cli
eas.json
はサンプルのものをそのまま使う。
{
"build": {
"development": {
"developmentClient": true,
"distribution": "internal"
},
"development-simulator": {
"developmentClient": true,
"ios": {
"simulator": true
}
},
"production": {}
}
}
この後、iOS デバイスでテストするためには ad-hoc provisioning を使うので Developer アカウントが必要。また、EAS を使うためには Expo の有料会員である必要がある。
Android 端末で試すのが一番簡単。Application ID だけ聞かれるので適当に決める。
$ eas build --profile development --platform android
あとは EAS 上でビルドが実行される。ローカルでビルドすることもできるが、Xcode や Android Studio が必要。
ビルドが完了するとターミナル上に QR コードが表示される。QR コードを Andorid 端末で読み取る。Expo のページが表示されるので「インストール」をクリックしてインストールする。
これで、開発用の端末に Development Client がインストールできた。これは従来の Expo Go に相当するものなので、このあとはローカルで Metro サーバを起動して実際のアプリを動かす。
$ expo start --dev-client
あとはこれまでと同じ。QR コードを読み取ればアプリが起動する。
ネイティブコードに変更がない限り、Development Client のビルドは必要ないので、あとは開発端末上でホットリロードしながら開発を進められる(シミュレータを使いたい場合はローカルでビルドが必要になるが...)
EAS が正式リリースされ、無料ユーザーでも使えるようになった。すごい
EAS build
-
app.config
で環境変数を利用している場合は、eas.json
で環境変数を指定する - Configuring EAS Build with eas.json - Expo Documentation
- また、
expo start --dev-client
実行時にも環境変数の指定が必要- 例えば、
API_URL=http://api.example.com/
expo start --dev-client
- 例えば、
やっと、今のプロジェクトを EAS build に移行しつつある。普通に動いてるっぽい。