Slide 1

Slide 1 text

Yarn Workspaces × React Nativeの環境構築 React Native Matsuri

Slide 2

Slide 2 text

甲斐田 亮一 @camcam_lemon 株式会社CureApp フロントエンドエンジニア TypeScript, React / Figma Name Twitter Company Occupation Skills

Slide 3

Slide 3 text

Live Codingを行います

Slide 4

Slide 4 text

どういうふうにやっていくか インストールとビルド時間との勝負!! 環境構築中に発生するエラーを実際に確認しながら iOSとAndroidのシミュレーターが正常に立ち上がるまでを行います 解説はインストールやビルドの待ち時間に...

Slide 5

Slide 5 text

開発環境 ! node_modulesを生成するモード ! できる限りhoistingする ! yarn v3(Berry) ! React Native v0.65.1 ! 環境構築は公式の「Setting up the development environment」に従う ! シミュレーターは設定済みを想定 ! React v17.0.2

Slide 6

Slide 6 text

開発環境 Xcode v13.0 CocoaPods v1.11.2 シミュレーター iPhone 12(iOS 15) : iPhone :Pixel_3a_API_30 Android

Slide 7

Slide 7 text

構成 packages package.json ...package共通のモジュールを記述(ESLintやprettier) mobile ...React Native製のネイティブアプリ web ...React製のウェブアプリ root node_modules ...hoistingするのでここにほぼ全てのモジュールが入る

Slide 8

Slide 8 text

環境構築の手順(pod installまで) ① Berryの設定 ② rootのpackage.jsonにworkspacesフィールドを追加 ③ webの雛形を作成 ④ モジュールのインストール(yarn install) ⑤ react-native-cliでテンプレート作成 ⑥ Podfileのパスを修正してpod install

Slide 9

Slide 9 text

yarn v3(Berry)について 4 Berryの設定した際に自動で作成される 4 node_modulesやhoistingの設定もここで変更できる 4 設定はyarnrc.ymlに記述する 4 TypeScriptの@typesを自動で追加などができる(@yarnpkg/plugin-typescript) 4 プラグインによる拡張が可能 4 再現性のないエラーがよく起こる 4 初回設定時は空のyarn.lockがないとインストールできない(できる時もある) 4 yarn install ではなく yarn を使うべし(hoistingがぶっ壊れる時がある) Ô プロダクション運用ではv2の利用を推奨 4 yarn v3はまだ不安定

Slide 10

Slide 10 text

.yarnrc.ymlの設定 .yarnrc.yml

Slide 11

Slide 11 text

hoistingとは 1 雑に言うと同一モジュールをまとめて容量削減する 1 ルートのnode_modulesに巻き上げる(hoist)のでhoisting 1 bootstrapが速くなる 1 yarnが依存関係を整理して巻き上げるかどうかを決めている 1 依存関係はルートのyarn.lockで全て管理される 1 プロジェクトとの相性の良し悪しがある 1 使っているモジュールによってはひと手間加えないといけないことがある 1 React Nativeはその最たる例

Slide 12

Slide 12 text

hoistingのイメージ root packages @pkgA/node_modules @pkgB/node_modules node_modules A(v1.0.0) A(v1.0.0) B(v1.0.0) A(v2.0.0) B(v1.0.0) C(v1.0.0) root packages @pkgA/node_modules @pkgB/node_modules node_modules A(v1.0.0) B(v1.0.0) C(v1.0.0) A(v2.0.0) Berryでは全てhoistされたpackageには node_modulesが作成されない ※

Slide 13

Slide 13 text

モノレポだから動かない hoistingされたから動かない 動かすにはひと手間必要で、その原因は主に2つ hoistingがややこしくする React Native関連のモジュールがhoistingされなければエラーは起きない 一度動いてもhoistingが崩れれば動かなくなる react-native-cliはコマンドを実行したディレクトリーをベースにテンプレートを生成する とはいえyarn installの速度改善の恩恵は大きい 一度動き出すと安定はする(hoistingが崩れることは稀) ReactとReact Nativeのバージョンは必ず揃え、固定するのが望ましい 相性が良いとは言えない yarn workspacesとReact Native

Slide 14

Slide 14 text

操作のまとめ(yarn iosまで) ① 各種モバイルのnode_modulesの参照先変更 ② ルートディレクトリーにMetroの設定ファイルを作成

Slide 15

Slide 15 text

node_modulesの参照先をrootに変更する % Podfile % mobile.xcodeproj/project.pbxproj % iosフォルダ % build.gradle % settings.gradle % app/build.gradle % androidフォルダ

Slide 16

Slide 16 text

Podfileの設定は環境によって異なる D XCodeとiOSのバージョンで異なるエラーが発生する D Xcode 12.5 以上で発生するエラー D iOS 15 のシミュレーターで発生するエラー D 2021/9/29に修正コミットがmainブランチに取り込まれたのでもうすぐ直る D 2021/10/2にv.0.66.0がリリースされ、上記エラーは修正された D いずれのエラーもFlipperで起こる D node_modulesのパスを変更するのは共通

Slide 17

Slide 17 text

RN 0.65.1 以下かつ XCode12.5 以上の場合 packages/mobile/ios/Podfile

Slide 18

Slide 18 text

RN v0.65.1 以下かつ iOS 15.0 以上の場合 P React Nativeのリポジトリに同問題と思われるissueが何件もある P Xcode 13.0 の対応でも動くようになるので、Xcode側の問題かも? P まだリリースされたばかりで情報が錯綜している P CocoaPodsを最新にあげる(react-native-cliのテンプレートはこれで動く) P project.pbxprojにswiftライブラリーの参照を足す P useFlipperをコメントアウトする P https://github.com/facebook/react-native/issues/31733 P いろいろ試して頑張って動かすしかない P RN v0.66.0だと上記問題は発生しない

Slide 19

Slide 19 text

packages/mobile/ios/Podfile Podfileの設定

Slide 20

Slide 20 text

Metroについて 3 Metroが(hoistingされていれば)ルートのnode_modulesにいるため 3 開発時はrootのmetro.config.jsを優先的に見る e プロダクションビルド時にはmobile/metro.config.jsが参照されるので注意 3 設定ファイルはルートディレクトリーに作成する 3 設定しないと全ての変更を監視してしまうのでMetroが重くなる 3 watchFoldersで変更を監視したいフォルダへのパスを文字列で指定 3 blockListで変更を無視したいフォルダへのパスを正規表現で指定 3 blockListはかつてblackListREという名前だった 3 モノレポではwatchFoldersとblockListは必須

Slide 21

Slide 21 text

metro.config.js Metroの設定(開発時)

Slide 22

Slide 22 text

packages/mobile/metro.config.js Metroの設定(プロダクションビルド時)

Slide 23

Slide 23 text

iOSの起動はこれで完了

Slide 24

Slide 24 text

Androidは動くけど動いてない

Slide 25

Slide 25 text

操作のまとめ(yarn androidまで) ① app/build.gradleのcliパスを編集 ② android起動時にjetifierを使わないようにする ③ 起動はできたが画像が読み込めない ④ 画像を読み込めるようにMetroの設定を編集する

Slide 26

Slide 26 text

androidのcliについて $ cliのパスの通し方は色々方法がある $ rootプロパティでカレントの階層を変更できる $ @react-native-community/cliを実行するjsファイルを作成する $ @react-native-community/cliが実行さえできればいい

Slide 27

Slide 27 text

app/build.gradleの設定(該当部だけ) packages/mobile/android/app/build.gradle

Slide 28

Slide 28 text

jetifierについて 2 Androidにとって深く歴史的経緯のある存在 2 AndroidXという単語もこの歴史に関わってくる登場人物 2 Androidは同じ処理でもAPIレベルでメソッド名やクラス名が違うことがある 2 jetifierはAPIレベルを見てよしなにしてくれる 2 今の時代なら--no-jetifierでも(きっと)大丈夫 2 有名所のライブラリーはほぼ対応してるので、現在は起動しなくても良い 2 jetifierは実行時のディレクトリーにnode_modulesフォルダがなくても落ちるので注意 2 jetifierが必要な場合は、別プロセスで起動する

Slide 29

Slide 29 text

Androidは画像を読み込ませるために一工夫必要 3 Metroに黒魔術を施す 3 Metroはローカルにnodeサーバを立ててシミュレーターを動かしてる 3 ホスト先を変更し、特定のリクエストを書き換えることで画像が読み込める 3 dark/magicの正体はビルドするとわかる 3 どこを探してもこのフォルダは存在しない 3 Android用にJavaScriptをビルド(≠Release Build APK)すると尻尾を掴める

Slide 30

Slide 30 text

dark_magicが出現する

Slide 31

Slide 31 text

Metroの設定 metro.config.js

Slide 32

Slide 32 text

Androidも動いた

Slide 33

Slide 33 text

まとめ # yarnが何をhoistingしてるかを確認する # React Native関連のモジュールのバージョンは固定するのも手 # 古い情報もあり今では変わってる設定もあるので注意 # この資料もいずれ古くなって色々変わるかもしれない # キツいのは最初だけ、動き出せば安定する # 今回作ったデモの完成版はこちら # https://github.com/camcam-lemon/react-native-monorepo-template

Slide 34

Slide 34 text

ご清聴ありがとうございました! 次ページにAppendixがあるよ→

Slide 35

Slide 35 text

Appendix

Slide 36

Slide 36 text

① yarn v3(Berry)の設定 ② blackListReについての補足 ③ Xcodeにswiftへのパスを通す ④ web, mobile共通のpackageの作成と読込設定 やりたかったけどできなかったものたち

Slide 37

Slide 37 text

yarn v3を設定するまでに実行したコマンド > yarn set version berry // 最新バージョンのBerryをインストール。berryは任意のバージョンに変更できる > yarn plugin import typescript // TypeScript用のpluginのインポート // プラグインはyarn.lockやnode_modulesがないと実行できなかったりする yarnコマンドが何も叩けなくなったら .yarnフォルダを消して再度yarn set version berryから始めた方が良いです

Slide 38

Slide 38 text

blackListREについての補足 0 昔の記事でよくでてくるけど現在は使えない 0 blackListREプロパティにblackList関数でパスを渡す記事がよくヒットする 0 Metro v0.60.0を起点に変わった 0 v0.60.0でblackList関数はexclusionListにリネーム 0 v0.61.0でblackListREプロパティはblockListにリネーム 0 チームメンバで使っているOS(Windows, Max)が違うのであれば使った方がいい 0 デフォルトで__tests__フォルダを無視している 0 exclusionListはパス区切り文字の整形などを行う

Slide 39

Slide 39 text

Metro 0.60.0 以下から Metro 0.66.0 への移行

Slide 40

Slide 40 text

project.pbxprojにswiftライブラリーの参照を足す packages/mobile/ios/mobile.xcodeproj/project.pbxproj + 2箇所のLIBRARY_SEARCH_PATHSにパスを足す Apple M1のシミュレーターもこの対応で動くらしい

Slide 41

Slide 41 text

package共通のモジュールを作成する B web, mobileからimportして使うことを想定 B MetroのwatchFoldersでpackageへのパスを渡す B 設定しないとパスの解決ができなくてビルドが失敗する B 共通モジュールの中の変更はリアルタイムに監視されている B web(webpack)は追加の設定はいらない B package.jsonへの追加だけで動く

Slide 42

Slide 42 text

構成 packages package.json ...package共通のモジュールを記述(ESLintやprettier) common-modules ...package共通のユーティリティ mobile ...React Native製のネイティブアプリ web ...React製のウェブアプリ root node_modules ...hoistingするのでここにほぼ全てのモジュールが入る

Slide 43

Slide 43 text

metro.config.js Metroの設定

Slide 44

Slide 44 text

package.jsonの設定