Android
Xcode
reactnative
expo

expo detachとreact-native initにおける比較

何をやったのか

$ react-native init$ exp detachでできたアプリについて比較を行った。
ちなみに、以下の記事の続きみたいな感じです。
Expo detachから各シミュレーター起動まで

そもそもなぜ Detachするのか?

Expo公式のドキュメントにも書いてあるが、Expoがデフォルトで対応していないNativeの機能を追加したい時に、初めてDetachする。ただしこれによって、しなければならないことは以下の通り。

  • アプリのStand alone化の際には、Document通りにはできず自力でやらなければならない
  • NativeCodeの実装 (特にデフォルト対応のPush通知だけはDetachによってサポートされなくなるので、自力でNative実装が必要)
  • ReactNativeのVersion上げに対するBreaking Changesも、自力対応しなければならない

参考:You should not detach if:

実際の比較

フォルダ構成

react-native initの場合

root/
 ├ __tests__/
 │
 ├ android/
 │       ├ .grandle/
 │       ├ app/
 │       ├ build/
 │       ├ build.grandle
 │       ├ gradle/
 │       ├ gradle.properties
 │       ├ gradlew
 │       ├ gradlew.bat
 │       ├ keystores/
 │     └ setting.grandle
 │
 ├ ios/
 │   ├ build/
 │   ├ AppName/
 │   ├ AppName-tvOS/
 │   ├ AppName-tvOSTests/
 │   ├ AppNamee.xcodeproj/
 │   └ AppNameTests/
 │ 
 ├ node_modules/
 │
 ├ .babelrc
 ├ .flowconfig
 ├ .watchmanconfig
 ├ .gitattributes
 ├ .gitignore
 ├ App.js
 ├ app.json
 ├ index.js
 ├ package.json
 └ yarn.lock

exp detachの場合

root/
 ├ .expo/
 ├ .expo-source/android/
 │
 ├ android/
 │     ├ .gradle/
 │       ├ .idea/
 │       ├ app/
 │       ├ build/
 │       ├ build.grandle
 │       ├ gradle/
 │       ├ gradle.properties
 │       ├ gradlew
 │       ├ gradlew.bat
 │       └ setting.grandle
 │
 ├ ios/
 │     ├ build/
 │     ├ AppName/
 │     ├ AppName.xcodeproj/
 │     ├ AppName.xcworkspace/
 │     ├ Pods/
 │     ├ Podfile
 │     └ Podfile.lock
 │ 
 ├ node_modules/
 │
 ├ .babelrc
 ├ .flowconfig
 ├ .watchmanconfig
 ├ .gitignore
 ├ App.js
 ├ app.json
 ├ App.test.js
 ├ package.json
 └ yarn.lock

Diff

概要

  • Root直下のアプリの根本のファイル群については、違いはほぼない (index.jsの有無くらい)
  • initの場合は、テストの為のフォルダーが作られる
  • detachの場合は、.expo-sourceが生成され、実際にandroidのビルドには必要なファイル群である(ないと実際にはビルドできなかった)
  • ios/android/は、それぞれ構成が大きく異なる

ios/

exp detach

  • CocoaPodsで、ネイティブライブラリを管理するようになる
  • $ react-native linkは使用可能になる
  • AppName.xcworkspaceからビルドを行う

react-native init

  • $ react-native linkがデフォルトで可能
  • AppName.xcodeprojからビルドは行う
  • tvOS用のファイルも存在する

参考: Cocoapodsで入れたライブラリをReact Nativeとbridgeして使う

android/

exp detach

  • MavenとGrandleの共存関係になる(.expo-source/android/mavenをコンパイルしに行く)
  • MavenとかGrandleとか、そこらへんのビルド構造がもうすでにある状態

react-native init

  • Grandleでビルド
  • 依存関係はほぼない、自分で一から色々カスタマイズはできそう(Kotlin使ったりとか)
  • keystoresというフォルダーが生成される

参考: Java製アプリを Eclipse から実行したことしかない新人に「ビルドツールとは?」を説明してみる…そして CI へ

DetachについてのSummary

色々見てきましたが、やっぱりDetach後のプロジェクトを触って行くには、Nativeの知識がかなり必要だと感じました。(Native知識がないので、そこまで詳しく分析もできなかった...)

あとは、react-nativeのライブラリがexpoのforkしたものを使わなければならないのは、割と致命傷な気がしました。

参考: Expo detachから各シミュレーター起動まで 2.package.jsonの書き換え

Pros

基本的には、お互いのいいとこ取りできるのが利点

  • ReactNativeのライブラリを自由に追加できるようになる
  • Expoのデフォルトの便利APIが基本的にはそのまま使える

Cons

基本的には、今までExpoがやってくれたNative周りの連携を、自力で修正する必要があるのが欠点(しかも、Expoがごにょごにょした後で)

  • Expo XDEが使えなくなる
  • react-nativeのversion管理がかなり大変そう
  • ios/ , android/以下の管理がNative知識がないと大変そう
  • Nativeアプリのリリース周りに詳しくないと、アプリのリリースまでが大変そう