メインコンテンツまでスキップ

Config Plugins対応

危険

Expo SDK 46以下のPrebuildはプロキシ環境下で動作しません。 Config Pluginsに対応するとPrebuildの実行が必須となります。プロキシ環境下で開発を進めるプロジェクトはご注意ください。

おそらく次のPull Requestに関連する不具合と推測しております。

このPull RequestはExpo SDK 47で取り込まれております。Expo SDK 47以降においては、プロキシ環境下でもPrebuildが動作することを確認出来ております。 プロキシ環境下で開発を進めるプロジェクトにおいては、Expo SDK 47へのアップグレード対応と併せてConfig Pluginsに対応することをお勧めします。

Config Plugins対応の背景

ネイティブ機能を柔軟に組み込むため、このアプリではBare workflowを採用しました。 その結果、次の課題が生じました。

Expo SDKのアップグレードに時間がかかる。 Expo SDKのアップグレードに対応するには、ネイティブプロジェクトの設定やコードの変更が必要でした。 この作業は細心の注意とネイティブ知識が必要で、対応できる人材が限られ非常に時間がかかりました。

ネイティブプロジェクトへの変更を管理しづらい。 Bare workflowでは、Expoで用意されたネイティブプロジェクトのテンプレートを管理します。 アプリは必要に応じてアプリ独自の変更をネイティブプロジェクトに加えます。 元から用意されたリソースと後から変更したリソースの区別が難しく、どこに何を何のために追加・修正したのかの管理が困難でした。

これらの課題を解決するため、Config Pluginsに対応しました。

Config PluginsはAndroidやiOSプロジェクトのネイティブ設定やコードをカスタマイズできる機能です。 ネイティブ設定やコードの変更をプラグインとして管理できるため、上記課題への解決策となります。 Config Pluginsの概要はConfig Pluginsについてを参照してください。

Config Plugins対応に伴う主な変更点

ビルドバリアント

Config Plugins対応に伴い、ビルドバリアントの考え方を見直しました。 見直した理由は次のとおりです。

  • デバッグビルドとリリースビルド以外のビルドタイプを用意するのが難しい
  • ビルドタイプとプロダクトフレーバーの柔軟な組み合わせが必要な場面はあまりない

今後はアプリの利用シーンに応じて、環境変数とビルドタイプの組み合わせでビルドを管理します。 詳しくはビルドタイプを参照してください。

react-native-config

react-native-configを導入することで、ネイティブとReactで同じ環境変数を使用できました。 しかし、react-native-configの設定は難しく、新たな環境を追加するには技術力と時間を要しました。 そこで、react-native-configを使用しないことにしました。 環境変数はExpo Configでの管理となります。 詳しくはアプリ特有の設定値を参照してください。

このアプリで実施したConfig Pluginsの対応手順

このアプリでは、次の作業を上から順に実施してConfig Pluginsに対応しました。

アップグレードを実施したPull Requestは次のとおりです。具体的な修正内容はこちらを参照してください。

リソースをassetsへ移動

次のリソースをassetsフォルダへ移動しました。

  • Android(アイコン)
移動元([プロジェクトルート]/android/app/src/)移動先([プロジェクトルート]/assets/android/)
debug/res/mipmap-xxxhdpi/ic_launcher_foreground.pngic_launcher_foreground_local.png
releaseInHouse/res/mipmap-xxxhdpi/ic_launcher_foreground.pngic_launcher_foreground_stg.png
main/res/mipmap-xxxhdpi/ic_launcher_foreground.pngic_launcher_foreground_prod.png
  • Android(スプラッシュスクリーン)
移動元([プロジェクトルート]/android/app/src/)移動先([プロジェクトルート]/assets/android/)
main/res/drawable-hdpi/splashscreen_footer.pngsplashscreen/hdpi/splashscreen_footer.png
main/res/drawable-hdpi/splashscreen_footer_background.pngsplashscreen/hdpi/splashscreen_footer_background.png
main/res/drawable-hdpi/splashscreen_foreground.pngsplashscreen/hdpi/splashscreen_foreground.png
main/res/drawable-ldpi/splashscreen_footer.pngsplashscreen/ldpi/splashscreen_footer.png
main/res/drawable-ldpi/splashscreen_footer_background.pngsplashscreen/ldpi/splashscreen_footer_background.png
main/res/drawable-ldpi/splashscreen_foreground.pngsplashscreen/ldpi/splashscreen_foreground.png
main/res/drawable-mdpi/splashscreen_footer.pngsplashscreen/mdpi/splashscreen_footer.png
main/res/drawable-mdpi/splashscreen_footer_background.pngsplashscreen/mdpi/splashscreen_footer_background.png
main/res/drawable-mdpi/splashscreen_foreground.pngsplashscreen/mdpi/splashscreen_foreground.png
main/res/drawable-xhdpi/splashscreen_footer.pngsplashscreen/xhdpi/splashscreen_footer.png
main/res/drawable-xhdpi/splashscreen_footer_background.pngsplashscreen/xhdpi/splashscreen_footer_background.png
main/res/drawable-xhdpi/splashscreen_foreground.pngsplashscreen/xhdpi/splashscreen_foreground.png
main/res/drawable-xxhdpi/splashscreen_footer.pngsplashscreen/xxhdpi/splashscreen_footer.png
main/res/drawable-xxhdpi/splashscreen_footer_background.pngsplashscreen/xxhdpi/splashscreen_footer_background.png
main/res/drawable-xxhdpi/splashscreen_foreground.pngsplashscreen/xxhdpi/splashscreen_foreground.png
main/res/drawable-xxxhdpi/splashscreen_footer.pngsplashscreen/xxxhdpi/splashscreen_footer.png
main/res/drawable-xxxhdpi/splashscreen_footer_background.pngsplashscreen/xxxhdpi/splashscreen_footer_background.png
main/res/drawable-xxxhdpi/splashscreen_foreground.pngsplashscreen/xxxhdpi/splashscreen_foreground.png
  • iOS(アイコン)
移動元([プロジェクトルート]/ios/SantokuApp/Images.xcassets/)移動先([プロジェクトルート]/assets/ios/)
AppIcon.debug.appiconset/1024x1024@1x.pngic_local.png
AppIcon.house.appiconset/1024x1024@1x.pngic_stg.png
AppIcon.appiconset/1024x1024@1x.pngic_prod.png

リソースをtemplateへ移動

次のリソースをtemplateフォルダへ移動しました。 これらのリソースはアプリ独自に作成したConfig Pluginsで利用します。

  • Android(スプラッシュスクリーン)
移動元([プロジェクトルート]/android/app/src/)移動先([プロジェクトルート]/config/plugin/template/android/app/src/)
main/res/drawable/splashscreen.xmlmain/res/drawable/splashscreen.xml
  • Android(ソースコード)
移動元([プロジェクトルート]/android/app/src/)移動先([プロジェクトルート]/config/plugin/template/android/app/src/)
main/java/jp/fintan/mobile/santokuapp/MainActivity.javamain/java/com/helloworld/MainActivity.java
main/java/jp/fintan/mobile/santokuapp/demo/throwerror/ThrowErrorModule.javamain/java/com/helloworld/ThrowErrorModule.java
main/java/jp/fintan/mobile/santokuapp/demo/throwerror/ThrowErrorPackage.javamain/java/com/helloworld/ThrowErrorPackage.java
  • iOS(スプラッシュスクリーン)
移動元([プロジェクトルート]/ios/SantokuApp/Images.xcassets/)移動先([プロジェクトルート]/config/plugin/template/ios/HelloWorld/Images.xcassets/)
SplashScreenBackground.imageset/Contents.jsonSplashScreenBackground.imageset/Contents.json
SplashScreenBackground.imageset/background.pngSplashScreenBackground.imageset/background.png
SplashScreenFooter.imageset/Contents.jsonSplashScreenFooter.imageset/Contents.json
SplashScreenFooter.imageset/splashscreen_footer@1x.pngSplashScreenFooter.imageset/splashscreen_footer@1x.png
SplashScreenFooter.imageset/splashscreen_footer@2x.pngSplashScreenFooter.imageset/splashscreen_footer@2x.png
SplashScreenFooter.imageset/splashscreen_footer@3x.pngSplashScreenFooter.imageset/splashscreen_footer@x.png
SplashScreenFooterBackground.imageset/Contents.jsonSplashScreenFooterBackground.imageset/Contents.json
SplashScreenFooterBackground.imageset/splashscreen_footer_background@1x.pngSplashScreenFooterBackground.imageset/splashscreen_footer_background@1x.png
SplashScreenFooterBackground.imageset/splashscreen_footer_background@2x.pngSplashScreenFooterBackground.imageset/splashscreen_footer_background@2x.png
SplashScreenFooterBackground.imageset/splashscreen_footer_background@3x.pngSplashScreenFooterBackground.imageset/splashscreen_footer_background@3x.png
SplashScreen.imageset/Contents.jsonSplashScreenForeground.imageset/Contents.json
SplashScreen.imageset/SplashScreenForeground.imageset/splashscreen_foreground@1x.pngSplashScreenForeground.imageset/splashscreen_foreground@1x.png
SplashScreen.imageset/SplashScreenForeground.imageset/splashscreen_foreground@2x.pngSplashScreenForeground.imageset/splashscreen_foreground@2x.png
SplashScreen.imageset/SplashScreenForeground.imageset/splashscreen_foreground@3x.pngSplashScreenForeground.imageset/splashscreen_foreground@3x.png
  • iOS(ソースコード)
移動元([プロジェクトルート]/ios/)移動先([プロジェクトルート]/config/plugin/template/ios/)
Demo/RCTThrowErrorModule.hHelloWorld/RCTThrowErrorModule.h
Demo/RCTThrowErrorModule.mHelloWorld/RCTThrowErrorModule.m
  • iOS(xcconfig)
移動元([プロジェクトルート]/ios/)移動先([プロジェクトルート]/config/plugin/template/ios/)
PersonalAccount.xcconfig.templateHelloWorld/PersonalAccount.xcconfig.template
  • iOS(Storyboard)
移動元([プロジェクトルート]/ios/)移動先([プロジェクトルート]/config/plugin/template/ios/)
SantokuApp/SplashScreen.storyboardHelloWorld/SplashScreen.storyboard

android、iosフォルダの削除

androidiosフォルダを削除しました。

pluginのソースコード追加

config/plugin/srcフォルダにアプリ独自のConfig Pluginsを作成しました。 それぞれの概要はアプリで独自に作成したConfig Pluginsを参照してください。

Expo configの追加

次のExpo configを用意しました。

ファイル概要
app.config.jsアプリ全体のベースとなる設定です。環境毎に違う設定値は、prodの設定を定義しています。prodと違う設定を定義する場合は、各環境ごとの設定ファイル(app.config.xxx.json)で再定義しています。
config/app.config.local.jsローカル環境で開発する際の設定を定義しています。
config/app.config.stg.jsステージング環境のアプリを配信する際の設定を定義しています。
config/app.config.prod.js本番環境のアプリを配信する際の設定を定義しています。

詳しくは環境の切り替えを参照してください。

patchesの追加

IOSConfig.XcodeUtils.addResourceFileToGroupでファイルを追加した際に、追加したファイルのIDが取得できません。 そのため、追加したファイルのIDを参照するような設定をできない事象が発生しました。 そこで、IOSConfig.XcodeUtils.addResourceFileToGroupにファイルのIDを指定できるパッチを当てました。

ダミーのFirebase設定ファイルの追加

local環境で使用するダミーの設定ファイルを用意しました。

  • Android: [プロジェクトルート]/google-services-dummy.json
  • iOS: [プロジェクトルート]/GoogleService-Info.Dummy.plist

詳しくはFirebaseの設定ファイルを参照してください。

依存ライブラリの追加・変更

exporeact-nativeexpo-status-bar

Prebuildの際にexporeact-nativeのバージョンが更新され、expo-status-barへの依存性が追加されました。 Prebuildの際のdependenciesフィールドの更新については、Expoの公式記事を参照してください。

expo-build-properties

アプリ独自のConfig Pluginsで使用するため、expo-build-propertiesを依存ライブラリに追加しました。

react-native-config

react-native-configは使用しないことにしたので、依存ライブラリから削除しました。

ソースコードの修正

環境変数の扱いを変更したことにより、[プロジェクトルート]/src/bases/core/configs/AppConfig.tsを修正しました。 詳しくはアプリ特有の設定値を参照してください。