🕑

Expo bare workflowにしたアプリをexpo-dev-clientとeas buildを使ってManagedに戻す

2022/06/16に公開

こんにちは。
いくつかの React Native アプリを個人開発している HAL と申します。
タイトルの通り、一度 eject して Bare workflow にしたアプリを、Managed に戻す対応をやってみたのでまとめてみます。

Managed workflow と Bare workflow についてよくわからんという方はこの辺を読みましょう。

https://docs.expo.dev/introduction/managed-vs-bare/

expo-dev-client とは

React Native の開発で Expo を利用している場合、どうしても Managed Workflow では使えないライブラリが使いたくなり、Bare workflow に切り替えて開発をしているという方もいると思います。
特に課金系のライブラリは Managed のままだと利用できないので、仕方なく eject して Bare workflow に切り替えている人もいるでしょう。

Expo SDK 42 で発表された expo-dev-client は、この状況を解消してくれる(かもしれない)ものになります。
簡単に言えば、Bare workflow にしないと使えなかったライブラリも Expo Managed のままで利用できるようになる、というものです。
ただ、完全に Managed workflow と同じ使い勝手というわけではなく、Managed と Bare の間の選択肢というイメージかなと思います。

Managed workflow だと、Expo Go アプリの上でサクッと動作確認をすることができます。
シミュレータでも実機でも、同じネットワークに繋がってさえいればいいのでとても簡単&快適ですね。

Bare workflow の場合は、素の React Native 同様に、Xcode や Android Studio でアプリをビルドしてシミュレータや実機にインストールする必要があります。
(コマンド実行も可能ですが、Xcode や Android Studio を使用して ios/android ディレクトリ配下のそれぞれのプロジェクトを管理する必要があります)
この ios/android ディレクトリ配下の管理やアップデートの追随がなかなか手間が多く、可能であれば避けたいなと思う部分です。

expo-dev-client + eas build は、ios/android ディレクトリを作成・管理することなく、Native 機能を使用するライブラリと共存させることができます。
ただ、Expo Go アプリの上で動作させることはできず、アプリをビルドしてパッケージングし、シミュレータや実機にインストールするという作業が発生します。
一度インストールしてしまえば、JavaScript の変更についてはホットリロードが使えるのでサクサク開発可能です。
ただ、ネイティブ機能を使用する(bare workflow で npx pod-install が必要になるような)ライブラリを追加した場合、リビルド・再インストールが必要になります。
この辺りの手間が増えるのが Managed と Bare の間という表現の所以です。

Bare workflow から  Managed + expo-dev-client に戻す前提条件

Bare workflow から Managed workflow + expo-dev-client に戻すには、一つ条件があります。

ios/android のプロジェクトディレクトリの中でいろいろカスタマイズをしていないこと

具体的には、React Native だけでは実現できないウィジェットの機能を追加していたり、ビルドスクリプトの中で独自の処理を実施していたりといったことです。
最終的には ios/android ディレクトリは削除してしまい、ビルド時に自動生成してもらうので、自動生成では対応できないようなことをしていると無理ということです。

その他に、一部のライブラリでは ios/android ディレクトリの中のファイルに手動で書き加える必要があるものがあったりします。
恐らくそういったものも対応できないと思った方が良いでしょう。
こればかりは、ライブラリによって違うので試してみないとなんとも言えませんが。

移行作業

では、実際にどのような手順で移行していくか記載します。
当然ですが、何かミスがあっても元に戻せるよう、作業用のブランチなどを作成して実施してください。

expo prebuild の実施

まず、自分の場合は expo prebuild を実施してみることにしています。

expo prebuild

このコマンドは eject する際同様に ios/android ディレクトリを作成するコマンドなのですが、これを実行することで Managed workflow で ios/android ディレクトリを自動生成した場合と現在の ios/android ディレクトリ配下のファイルの状態がどの程度違っているかということがわかります。
差分の状況はいつ頃 Bare workflow に切り替えたかによっても違うと思いますが、アイコン・スプラッシュスクリーン程度が差分に出るようであればあまり気にしなくて良いでしょう。
Info.plist とか Manifest.xml とかに大きく差分がある場合は、差分の内容を確認して、適宜 app.json に追記する、などの対応が必要になります。
(アクセス権限周りとかで自分で追記したものなどが該当してくると思います)

差分内容が一通り確認でき、対応が完了したら、ios/android ディレクトリは削除してしまいます。

expo-dev-client の追加と eas build の設定

続いて expo-dev-client を追加します。

expo install expo-dev-client

さらに eas build の設定を追加します。
まだ eas build を利用していない場合はこのコマンドを実行します。

# EAS CLIのインストール
npm install -g eas-cli

# Expoにログイン
eas login

# 設定ファイルの作成
eas build:configure

すると以下のようなファイルが作成されます。

eas.json
{
  "cli": {
    "version": ">= 0.53.1"
  },
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal"
    },
    "preview": {
      "distribution": "internal"
    },
    "production": {}
  },
  "submit": {
    "production": {}
  }
}

これにシミュレータでも実行できるように設定を追加します。

eas.json
{
  "cli": {
    "version": ">= 0.53.1"
  },
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal",
      // ここから
       "ios": {
        "buildConfiguration": "Debug",
        "simulator": true
      }
      // ここまで
    },
    "preview": {
      "distribution": "internal"
    },
    "production": {}
  },
  "submit": {
    "production": {}
  }
}

さらにビルド用のスクリプトを Package.json に追加しておきましょう。

Package.json(抜粋)
  "scripts": {
    "start": "expo start --dev-client",
    "build": "eas build --profile development --local",
  },

これで、npm run buildを実行することで、expo-dev-client を使用したアプリがローカルに作成されるようになります。
ビルドされると tar.gz ファイルに圧縮されるので、解凍して中のパッケージングされたアプリをシミュレータにドラッグ&ドロップすればインストールされます。
なお、ビルドをローカルではなくクラウド上で実行したい場合は、--localを除けばクラウド上でビルドしてくれます。
ビルド完了後、アプリをダウンロードしてやれば同様にテスト可能です。

ちなみに、iOS アプリの実機確認の場合は AdHoc の設定のためにデバイスの登録が必要だったりしますが、基本的には eas build の中でインタラクティブに確認されるので適宜答えていけばいいはずです。
また、eas build の設定は色々できることがあるんですが割愛します。

なお、ローカルでビルドすると tar.gz ファイルが作成されてしまうので、誤ってコミットしてしまわないよう、.gitignore*.tar.gzを追加しておいた方がいいかもしれません。

動作確認について

アプリのビルド・インストールまではできましたが、実際のテストはどうするのかというところも説明します。
まずは expo start で dev server を起動します。

expo start  --dev-client

先ほども書きましたが、シミュレータや実機にビルドしたアプリをインストールします。
インストールしたアプリを起動すると、以下のような画面が表示されます。

アプリ起動画面

development server が見つからない場合は「Fetch development servers」をタップしてみてください。
緑の丸がついた dev server が表示されたら、それを選択すると、JS コードのダウンロードが走ってアプリが実行されます。

最後に

以上で Expo Bare workflow に eject したプロジェクトを Managed + expo-dev-client に戻すことができました。
実際は、移行後にちゃんと動作するか全体的にテストをし直した方がいいと思います。
自分は特に大きな問題は発生していませんが、ライブラリによってはうまくいかないといった場合もあるかもしれません。
大幅な変更が入ることになるので、慎重に作業することをお勧めします。

Discussion