Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Yarn WorkSpaces × React Nativeの環境構築

Yarn WorkSpaces × React Nativeの環境構築

React Native Matsuriの登壇資料です。

A3ec73809a2105b3a9a829f983f6587e?s=128

camcam_lemon

October 02, 2021
Tweet

More Decks by camcam_lemon

Other Decks in Programming

Transcript

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

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

    Twitter Company Occupation Skills
  3. Live Codingを行います

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

  5. 開発環境 ! node_modulesを生成するモード ! できる限りhoistingする ! yarn v3(Berry) ! React

    Native v0.65.1 ! 環境構築は公式の「Setting up the development environment」に従う ! シミュレーターは設定済みを想定 ! React v17.0.2
  6. 開発環境  Xcode v13.0  CocoaPods v1.11.2  シミュレーター iPhone

    12(iOS 15) :  iPhone :Pixel_3a_API_30  Android
  7. 構成 packages package.json ...package共通のモジュールを記述(ESLintやprettier) mobile ...React Native製のネイティブアプリ web ...React製のウェブアプリ root

    node_modules ...hoistingするのでここにほぼ全てのモジュールが入る
  8. 環境構築の手順(pod installまで) ① Berryの設定 ② rootのpackage.jsonにworkspacesフィールドを追加 ③ webの雛形を作成 ④ モジュールのインストール(yarn

    install) ⑤ react-native-cliでテンプレート作成 ⑥ Podfileのパスを修正してpod install
  9. 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はまだ不安定
  10. .yarnrc.ymlの設定 .yarnrc.yml

  11. hoistingとは 1 雑に言うと同一モジュールをまとめて容量削減する 1 ルートのnode_modulesに巻き上げる(hoist)のでhoisting 1 bootstrapが速くなる 1 yarnが依存関係を整理して巻き上げるかどうかを決めている 1

    依存関係はルートのyarn.lockで全て管理される 1 プロジェクトとの相性の良し悪しがある 1 使っているモジュールによってはひと手間加えないといけないことがある 1 React Nativeはその最たる例
  12. 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が作成されない ※
  13.  モノレポだから動かない  hoistingされたから動かない  動かすにはひと手間必要で、その原因は主に2つ  hoistingがややこしくする  React

    Native関連のモジュールがhoistingされなければエラーは起きない  一度動いてもhoistingが崩れれば動かなくなる  react-native-cliはコマンドを実行したディレクトリーをベースにテンプレートを生成する  とはいえyarn installの速度改善の恩恵は大きい  一度動き出すと安定はする(hoistingが崩れることは稀)  ReactとReact Nativeのバージョンは必ず揃え、固定するのが望ましい  相性が良いとは言えない yarn workspacesとReact Native
  14. 操作のまとめ(yarn iosまで) ① 各種モバイルのnode_modulesの参照先変更 ② ルートディレクトリーにMetroの設定ファイルを作成

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

    settings.gradle % app/build.gradle % androidフォルダ
  16. 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のパスを変更するのは共通
  17. RN 0.65.1 以下かつ XCode12.5 以上の場合 packages/mobile/ios/Podfile

  18. 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だと上記問題は発生しない
  19. packages/mobile/ios/Podfile Podfileの設定

  20. 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は必須
  21. metro.config.js Metroの設定(開発時)

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

  23. iOSの起動はこれで完了

  24. Androidは動くけど動いてない

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

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

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

  28. jetifierについて 2 Androidにとって深く歴史的経緯のある存在 2 AndroidXという単語もこの歴史に関わってくる登場人物 2 Androidは同じ処理でもAPIレベルでメソッド名やクラス名が違うことがある 2 jetifierはAPIレベルを見てよしなにしてくれる 2

    今の時代なら--no-jetifierでも(きっと)大丈夫 2 有名所のライブラリーはほぼ対応してるので、現在は起動しなくても良い 2 jetifierは実行時のディレクトリーにnode_modulesフォルダがなくても落ちるので注意 2 jetifierが必要な場合は、別プロセスで起動する
  29. Androidは画像を読み込ませるために一工夫必要 3 Metroに黒魔術を施す 3 Metroはローカルにnodeサーバを立ててシミュレーターを動かしてる 3 ホスト先を変更し、特定のリクエストを書き換えることで画像が読み込める 3 dark/magicの正体はビルドするとわかる 3

    どこを探してもこのフォルダは存在しない 3 Android用にJavaScriptをビルド(≠Release Build APK)すると尻尾を掴める
  30. dark_magicが出現する

  31. Metroの設定 metro.config.js

  32. Androidも動いた

  33. まとめ # yarnが何をhoistingしてるかを確認する # React Native関連のモジュールのバージョンは固定するのも手 # 古い情報もあり今では変わってる設定もあるので注意 # この資料もいずれ古くなって色々変わるかもしれない

    # キツいのは最初だけ、動き出せば安定する # 今回作ったデモの完成版はこちら # https://github.com/camcam-lemon/react-native-monorepo-template
  34. ご清聴ありがとうございました! 次ページにAppendixがあるよ→

  35. Appendix

  36. ① yarn v3(Berry)の設定 ② blackListReについての補足 ③ Xcodeにswiftへのパスを通す ④ web, mobile共通のpackageの作成と読込設定

    やりたかったけどできなかったものたち
  37. yarn v3を設定するまでに実行したコマンド > yarn set version berry // 最新バージョンのBerryをインストール。berryは任意のバージョンに変更できる >

    yarn plugin import typescript // TypeScript用のpluginのインポート // プラグインはyarn.lockやnode_modulesがないと実行できなかったりする yarnコマンドが何も叩けなくなったら .yarnフォルダを消して再度yarn set version berryから始めた方が良いです
  38. 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はパス区切り文字の整形などを行う
  39. Metro 0.60.0 以下から Metro 0.66.0 への移行

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

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

    B web(webpack)は追加の設定はいらない B package.jsonへの追加だけで動く
  42. 構成 packages package.json ...package共通のモジュールを記述(ESLintやprettier) common-modules ...package共通のユーティリティ mobile ...React Native製のネイティブアプリ web

    ...React製のウェブアプリ root node_modules ...hoistingするのでここにほぼ全てのモジュールが入る
  43. metro.config.js Metroの設定

  44. package.jsonの設定