Expoのネイティブコード管理をBare WorkflowからContinuous Native Generation (CNG)に移管した話

<!-- 以下本文 -->
## はじめに
こんにちは！menu事業部フロントエンドエンジニアの午菴です。

私たちのチームでは、多くのアプリケーション開発にReact Native（Expo）を採用しています。

ExpoはReact Nativeアプリ開発を効率化する優れたフレームワークですが、アプリの成長に伴い、Managed Workflowだけでは対応できないネイティブ機能が必要になることがあります。かつては、その解決策としてBare Workflowへの移行が一般的でした。

しかし、Expoは進化を続けており、近年ではContinuous Native Generation（CNG）という新しいアプローチが登場しました。この記事では、私たちがBare WorkflowからCNGへの移行を決断した背景と、その具体的なプロセスについてご紹介します。

## Bare Workflowとその課題
ExpoのManaged Workflowは、コマンド一つでiOSとAndroidのバイナリを生成できる手軽さが大きな魅力です。しかし、SDKに含まれていないネイティブライブラリの利用や、Objective-C/Swift、Java/Kotlinでのネイティブコードの直接記述が必要になると、Managed Workflowのままでは対応できません。そのため、弊社がExpoを導入した当時はBare Workflowへの移行が必要でした。

Bare Workflowへ移行すると、プロジェクト内に`ios`および`android`ディレクトリが生成され、それぞれが独立したネイティブプロジェクトとして扱えるようになります。これにより、XcodeやAndroid Studioを用いて、ネイティブコードを自由に追加・修正することが可能になります。

一方で、Bare Workflowには特有の課題も存在しました。

私たちのプロジェクトでは、外部ライブラリの利用に伴いネイティブコードをカスタマイズしていたため、その点を考慮した更新作業が不可欠でした。特にカスタマイズしたネイティブコードの修正や動作確認に多大な工数がかかり、ネイティブ開発の知識が必要なため特定のメンバーに作業が集中しがちでした。

## Continuous Native Generation（CNG）とは
CNGは、Expoが2023年に導入した新しいアプローチです。これは、Managed Workflowの手軽さとBare Workflowの柔軟性を組み合わせた、いわば「第3の選択肢」と言えるでしょう。

CNGの主な特徴は以下の通りです。

- ネイティブコードの自動生成
  - 必要なネイティブコードを自動的に生成し、プロジェクトに統合します
  - Expo SDKのバージョンアップ時にも、カスタムした内容が反映されたネイティブコードが自動生成されるため、追従コストが大幅に削減されます
- 宣言的な設定
  - `app.json`や`app.config.js`を通じて、Expoが提供する設定項目をシンプルに管理できます
  - Expo標準の設定項目以外も、プラグインを実装することで同様に一元管理が可能です
  - 設定の変更は、ネイティブコードへ自動的に反映されます
- Managed Workflowの利点の維持
  - EAS BuildやOTAアップデートといった、Expoの便利な機能を引き続き利用できます
  - `expo prebuild`コマンドを実行することで、必要に応じてネイティブコードを生成できます

つまり、CNGはBare Workflowで抱えていた以下のような課題を解決します。

1. ネイティブコードの保守性向上
   - 手動でのネイティブコード管理が不要になり、メンテナンスコストが削減されます
   - プラグインが用意されているライブラリの導入・保守が容易にできます

2. 開発者体験の向上
   - TypeScriptを中心とした開発に、より一層集中できます

3. 柔軟性の確保
   - 必要に応じて、カスタムネイティブコードを追加することも可能です
   - プラグインが提供されている場合、サードパーティライブラリの統合も容易に行えます

## 移行プロセス
私たちのプロジェクトでは、以下のステップでBare WorkflowからCNGへの移行を進めました。

### 1. 事前準備と影響範囲の調査
- 現行ネイティブコードの棚卸し
  - カスタマイズしているネイティブコードの洗い出し
  - 利用している外部ライブラリのリストアップと互換性確認
- CNGでの代替手段の検討
  - Expoの標準設定でカバーできる範囲の特定
  - カスタムプラグイン開発が必要となる機能の洗い出し

### 2. プロジェクトの整理
- 依存ライブラリのバージョンを最新のパッチに更新
- `app.json` および `app.config.js` の設定見直しと最適化
  - アプリケーションの基本設定
  - 導入するプラグインの設定

### 3. プラグインの実装
- 以下の機能を実現するためのカスタムプラグインを実装
  - プッシュ通知関連の設定
  - 分析ツールの組み込み
### 4. チームでのレビュープロセス
- フロントエンドエンジニア全体でのレビューを実施
  - プロジェクトの変更内容について、全エンジニアへの説明と共有
  - シニアエンジニアによる実装内容の詳細な技術レビューと品質確認

### 5. 検証とデバッグ
- 各機能が期待通りに動作するかの網羅的な確認

## 移行の成果：開発効率と保守性の向上
CNGへの移行により、私たちは以下の具体的な成果を得ることができました。

### 1. 開発効率の大幅な向上
- 最も大きな変化は、Expo SDKのアップデート作業です。以前はネイティブコードの調整が必須でしたが、CNG移行後はネイティブコードに一切触れることなくアップデートを完了できました。これにより、**開発効率が向上しました。**

### 2. コードの保守性向上と属人化の解消
- ネイティブ関連の設定を `app.config.js` やプラグインに集約することで、一元管理が可能になりました。
- これにより、特定の開発者に依存していたネイティブコードのメンテナンス作業がなくなり、SDK更新作業の標準化にも繋がりました。

## まとめ
CNGへの移行は、私たちのプロジェクトにとって大きな転換点となりました。移行作業には相応の工数を要しましたが、長期的な視点で見れば、**開発効率の向上と保守性の改善**という十分な価値があったと思っています。

Expoは常に進化を続けており、CNGもまだ発展途上にあります。今後も新しい機能や改善が追加されることが期待されます。私たちも引き続きExpoや関連するモバイル開発の知見を深め、そのメリットを最大限に活かしながら、より良いアプリケーション開発を目指していきたいと考えています。

<!-- フッター -->

<hr>

### **▼カジュアル面談**<br>
弊社では、エンジニアの方々とのカジュアル面談を実施しています。
当社の技術スタックや働く環境等なんでもお話しできますので、ご興味をお持ちの方は、お気軽に下記リンクからメッセージをください！

https://pitta.me/matches/ofTvoQhMZFaD

### **▼採用情報**<br>
レアゾン・ホールディングスは、「世界一の企業へ」というビジョンを掲げ、「新しい"当たり前"を作り続ける」というミッションを推進しています。

現在、エンジニア採用を積極的に行っておりますので、ご興味をお持ちいただけましたら、ぜひ下記リンクからご応募ください。

https://recruit.reazon.jp/