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

Yarn WorkSpaces × React Nativeの環境構築

Yarn WorkSpaces × React Nativeの環境構築

React Native Matsuriの登壇資料です。

camcam_lemon

October 02, 2021
Tweet

More Decks by camcam_lemon

Other Decks in Programming

Transcript

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

    View Slide

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

    View Slide

  3. Live Codingを行います

    View Slide

  4. どういうふうにやっていくか
    インストールとビルド時間との勝負!!
    環境構築中に発生するエラーを実際に確認しながら

    iOSとAndroidのシミュレーターが正常に立ち上がるまでを行います
    解説はインストールやビルドの待ち時間に...

    View Slide

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

    View Slide

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

    iPhone
    :Pixel_3a_API_30
    Android

    View Slide

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

    View Slide

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

    View Slide

  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はまだ不安定

    View Slide

  10. .yarnrc.ymlの設定
    .yarnrc.yml

    View Slide

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

    View Slide

  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が作成されない

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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のパスを変更するのは共通

    View Slide

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

    View Slide

  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だと上記問題は発生しない

    View Slide

  19. packages/mobile/ios/Podfile
    Podfileの設定

    View Slide

  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は必須

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  30. dark_magicが出現する

    View Slide

  31. Metroの設定
    metro.config.js

    View Slide

  32. Androidも動いた

    View Slide

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

    View Slide

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

    View Slide

  35. Appendix

    View Slide

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

    View Slide

  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から始めた方が良いです

    View Slide

  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はパス区切り文字の整形などを行う

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  43. metro.config.js
    Metroの設定

    View Slide

  44. package.jsonの設定

    View Slide