yn2011's blog

技術メモ

Expo の Config Plugin とは何か

ざっくり要約

ExpoJavaScript (React Native) で iOS / Android / Web で動作するアプリケーションを開発できるフレームワーク。また、Expo で開発したアプリケーションをビルド・配布・アップデート可能な SaaS でもある。

フレームワークとしての Expo は、完全に JavaScript のみで開発が完結する Managed Workflow と、iOS / Android アプリの実装言語(Swift, Kotlin, etc)を使ってネイティブ領域の実装を変更可能にする Bare Workflow の 2つのモードがある。

一般的に、Firebase 等の外部サービスを利用するために SDK を組み込む際には、起動時処理の変更のためネイティブ領域のコードを変更する必要がある場合があるが Managed Workflow ではそれができなかった。

Config Plugin を使うことで Managed Workflow のまま JavaScript を使ってネイティブ領域のコードをメタプログラミング可能になるので Bare Workflow にする必要がなくなり、Web のフロントエンドエンジニアにとってはよりネイティブアプリの開発の敷居が下がる。

というのがざっくりとした Config Plugin に対する自分の理解だが、以下で更に掘り下げていきたい。

Conifig Plugin とは

公式ドキュメントから引用すると

Config plugins are a system for extending the Expo config and customizing the prebuild phase of managed builds.

https://docs.expo.dev/guides/config-plugins/

(訳)Config Plugin は Expo Config を拡張し、managed ビルドの prebuild フェーズをカスタマイズする仕組みです。

managed ビルドというのは Managed Workflow を利用したビルドのことだが、prebuild フェーズをカスタマイズするとはどういう意味なのか?

prebuild フェーズって何?

公式ドキュメントから引用すると

In Expo, prebuilding  is the process of generating the native runtime code for your React project. Prebuild can be used to automatically link and configure complex native modules that have implemented CocoaPods, autolinking, and config plugins.

https://github.com/expo/fyi/blob/main/prebuilding.md

(訳)prebuild とは、ネイティブランタイムコードを生成するプロセスのことです。PreBuild は Native Modules を自動的に結合、設定するために利用されます。

prebuild フェーズにおいて、Managed Workflow の場合は、/ios/android ディレクトリを生成し、Config Plugin として実装されたコードを元にディレクトリ内のネイティブランタイムコードを書き換える。

これは、仮に Config Plugin がなかったとしても、Managed Workflow のプロジェクトをアプリとしてビルドする場合には必ず通過するフェーズ。

最終的には Managed Workflow で開発していても普遍的なネイティブアプリとしてのコードベースに変換する必要がある(当然といえば当然)

Config Plugin は SDK 毎に開発

多くの場合、Config Plugin は外部の SDK(Native Modules) 毎に作成する。その SDK に必要なカスタマイズを SDK 毎に作成した Config Plugin に記述する。

なので、起動時処理などは SDK 間で同じファイルの同じ箇所を変更する競合が発生する可能性があるので注意をする必要がある。

Config Plugin が必要かどうかの判定方法

外部の SDK を利用したい場合に、Config Plugin が必要なのかどうかはどうやって判断すればいいのか?

ちなみに純粋な iOS / Android アプリ向けの SDK しか存在しない場合は React Native 向けの SDK を開発する必要があるので、Config Plugin 以前に最初はそこから始めるということになる。

既に公開されている Config Plugin がないかを探す

有名なサービスであれば既に公開されている場合もあるので、もし公開されているなら必要だと分かるし単純にそれを使えば OK

github.com

もし上記のリポジトリにもなく、サービスから公式に提供されているものがないのであれば、自分で必要性の有無を判断する必要がある。

SDK のドキュメントがある場合

ドキュメントを読み、ネイティブコードを書き換える必要があるかどうかを確認する。

例えば Repro なら SDK 導入手順がドキュメント化されていて、AppDelegate.m の書き換えが必要なことがわかる。

https://docs.repro.io/ja/dev/sdk/getstarted/react-native.html#id5

これは、Managed Workflow の場合は直接編集不可能なので Config Plugin を開発し、以下のような書き換え処理を TypeScript (JavaScript)で実装する。

const addImport = (contents: string): string => {
  if (contents.includes("@import <Repro/Repro.h>;")) {
    return contents;
  } else {
    return contents.replace(
      /#import "AppDelegate.h"/g,
      `#import "AppDelegate.h"
#import <Repro/Repro.h>
`,
    );
  }
};

SDK のドキュメントがない場合

とりあえず Config Plugin なしでビルドが通るか、きちんと動作するかを試してみるしかない。

Config Plugin を開発したい

自分が使いたい SDK に対して、どうやら公開されている Config Plugin もなさそうだしドキュメントを読むとネイティブコードを書き換えないといけないらしいという場合は自分で開発するしかない。ではどうやって開発するのか?

これは既存の実装を真似るしかない。。

自分は上記の Config Plugin を集めたリポジトリを参考にして何となく開発できたので、あまり尻込みせずに挑戦してみても良いと思う。