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

フロントエンドの Monorepo をやめてリポジトリ分割したワケ / Why did we stop using Monorepo on the frontend and split the repository?

フロントエンドの Monorepo をやめてリポジトリ分割したワケ / Why did we stop using Monorepo on the frontend and split the repository?

2024/06/25:

モノレポは、令和のソフトウェア開発における銀の弾丸か?
https://hack-at-delta.connpass.com/event/319792/

フロントエンドの Monorepo をやめてリポジトリ分割したワケ

坂井 学
ソフトウェアエンジニア

株式会社カミナシ

June 25, 2024
Tweet

More Decks by 株式会社カミナシ

Other Decks in Technology

Transcript

  1. 自己紹介 株式会社カミナシ ソフトウェアエンジニア 坂井 学 (Manabu Sakai) 略歴 2016 年に

    freee 株式会社に入社。 SRE チームでクラウド最適化やマ ルチプロダクトを支える仕組みづくりに取り組む。 もう一度 1 → 10 フェーズのサービス開発をやりたくて、2022 年に 株式会社カミナシへ入社。 BtoB SaaS は 3 社目でかれこれ 10 年以上の関わり。 カミナシでの仕事 主力サービスである「カミナシレポート」のサービス開発全般
  2. はじめに 今回の発表内容は「カミナシ エンジニアブログ」に書いた記事をベースにしています。 リポジトリ分割を行なって 1 年ほど経過したので、当時は書けなかったその後の話もお話しできれ ばと思っています。 https://kaminashi-developer.hatenablog.jp/entry/2023/05/22/goodbye-monorepo なお、カミナシでは Monorepo

    を否定しているわけではなく、Monorepo を採用しているチームも あります(それぞれのサービス開発チームがオーナーシップを持って意思決定しています)。 これ以降の話は、私が担当している「カミナシレポート」というサービスの話です。
  3. 2 つのフロントエンド カミナシレポートにおけるフロントエンド カミナシレポートには、2 つのフロントエンドが存在します。 • 管理者の方が使う Web アプリ (web)

    : React • 現場の方が使うモバイルアプリ (mobile) : React Native + Expo SDK どちらも Node.js と TypeScript を採用していることもあり、以前は Yarn Workspaces を使った Monorepo で運用されていました。
  4. harami_client ├── node_modules ├── package.json ├── packages │ ├── api_docs

    👈 OpenAPI 定義 │ │ └── package.json │ ├── mobile 👈 React Native + Expo SDK │ │ └── package.json │ └── web 👈 React │ └── package.json └── yarn.lock リポジトリ構成 node_modules はルートに配置されていて、各アプリケーションからは hoisting されて参照されて います。 harami はコード ネームです 🥩
  5. カミナシの Monorepo における課題 ① Monorepo ゆえの密な依存関係 ある時 Expo SDK をアップグレードするために

    mobile 側を React v18 に上げる必要性が出てきま した。しかし、ここで大きな問題が発生します。 • Expo SDK は React Native と React のバージョンに強く依存 • React のバージョンは web と mobile で揃える必要がある ◦ ルートの node_modules を共有しているため このことから web 側も同時に React v18 に上げる必要がありましたが、同時に進めれるほどの人 数はおらず後回しに…。
  6. カミナシの Monorepo における課題 ① Monorepo ゆえの密な依存関係 あるパッケージで利用しているライブラリを別のパッケージから利用できてしまうため、暗黙的な 依存関係も生まれてしまっていました。 web への変更が

    mobile に影響を与えてしまい(逆も然り)、不具合を発生させてしまったことも ありました。残念ながら適切に依存関係をコントロールできておらず、密な依存関係がデメリット になっていました。
  7. カミナシの Monorepo における課題 ③ アプリケーションのライフサイクルの違い Expo SDK はおよそ 3 か月おきにメジャーリリースが行われますが、最新を含めた

    2 つのバージョ ンしかサポートされず、それより古いものは Deprecated になります。 そのため常に最新バージョンを追いかけ続けることが重要ですが、お互いが密に依存している状況 だと対応コストが増えてしまい、通常の機能開発を圧迫してしまっていました。
  8. 補足 独立型と集中型 Monorepo で異なるバージョンの React を使う方法 で紹介されているような node_modules を共 有しない独立型にすれば、Monorepo

    構成を維持できたかもしれません(以下、記事より引用)。 • 集中型 Monorepo: ルートにすべてのライブラリをインストールして、それぞれのアプリケーションやモジュールで利用 ◦ すべてのライブラリがルートの package.json に記述される ◦ Monorepo 全体で同じバージョンのライブラリが利用される • 独立型 Monorepo: それぞれのアプリケーションやモジュールで必要なものをそれぞれでインストールする ◦ それぞれのアプリケーション・モジュールが使うライブラリがそれぞれの package.json に記述される ◦ それぞれのアプリケーション・モジュールで異なるバージョンのライブラリが利用できる
  9. リポジトリ構成(再掲) node_modules はルートに配置されていて、各アプリケーションからは hoisting されて参照されて います。 harami_client ├── node_modules ├──

    package.json ├── packages │ ├── api_docs 👈 OpenAPI 定義 │ │ └── package.json │ ├── mobile 👈 React Native + Expo SDK │ │ └── package.json │ └── web 👈 React │ └── package.json └── yarn.lock
  10. リポジトリ分割のステップ ① OpenAPI 定義の移行 packages 配下に web と mobile のソースコードがありますが、当時は

    OpenAPI 定義もクライア ント側のリポジトリに存在していました(クライアント側でしか OpenAPI 定義を使っていなかっ たため)。 リポジトリ分割の前に、まずはこの OpenAPI 定義を API サーバ側のリポジトリに移すことにしま した。
  11. リポジトリ分割のステップ ② OpenAPI の npm パッケージ化 1. OpenAPI 定義を API

    サーバ側のリポジトリに移行(ステップ ①) 2. npm パッケージ化して GitHub Packages に登録するワークフローを作成 3. web と mobile からは npm パッケージを参照するように変更
  12. まとめ 3 行まとめ • 当時のカミナシにおいては Monorepo のメリットを活かせず、密な依存関係が開発生産性を 落としていました • Monorepo

    はソフトウェア開発における銀の弾丸ではなく、サービスや組織の成長に伴って 最適解は変わってきます • リポジトリ分割は神経を使いますが、やってやれなくはないです(おそらく逆も然り)