モノレポ入門
モノレポ入門
mono
: 単一の
repo
: レポジトリ
その名の通り、単一のリポジトリで複数のプロジェクトを管理することです
例えば...
一つのサービスで
-
sample-project-backend
: バックエンド -
sample-project-user
: ユーザーフロント -
sample-project-partner
: 提携企業用管理画面 -
sample-project-staff
: 社内用管理画面
みたいに複数のリポジトリで一つのサービスが構築されているケース多いと思います。
モノレポで構成するとこんな感じで一つのリポジトリで管理することができます
apps/
└ user-front-sp
└ user-front-pc
└ backend
└ partner
└ staff
libs/
└ shared/
└ constants/
└ components/
粒度は様々(Uberさんの例)
├── apps
│ ├── iphone-driver
│ ├── iphone-eats
│ ├── iphone-rider
├── libraries
│ ├── analytics
│ ├── …
│ └── utilities
└── vendor
├── fbsnapshottestcase
├── …
└── ocmock
参考
https://eng.uber.com/ios-monorepo/より
モノレポの利点
- リソースの共有
- 同じリポジトリ内でimportすることが可能
- linterなどの設定を一元管理できる
- プロジェクトごとに自由な設計、技術選定
- なので、マイクロサービスなどとも相性がいい
生まれてくる疑問
- パッケージのバージョン管理大変だよね?
- CI/CDが遅くなるよね?
- 依存関係がわからず、意図しない変更が起こるよね?
- 共通部分で破壊的変更があった場合は影響範囲が広がるよね?
パッケージのバージョン管理大変だよね?
A. 大変なときもある
Nx
というツールでは、原則、同リポジトリ内にあるものは同じパッケージのバージョン管理下にある。
ので、バージョンを上げたい場合はすべて上げないといけない
lerna
では、各ディレクトリで別のパッケージ管理にある
これらは一長一短で、自分たちのサービスやチームの状態を考えて選ぶ必要がある
CI/CDが遅くなるよね?
A. ならない。Nx
などのツールとCI/CDを組み合わせることでむしろ早くなる
Nx
などのツールでは、コードの依存関係を管理し、変更の可能性がある部分のみを再ビルド、再テストします。
その他はキャッシュされたものを利用するため、変更に関係のない部分のビルドやテスト時間が短縮されます。
例えば
以下のような依存関係があったとしてrelay
という部分の変更に対して影響がありうるのはuser
とuser-e2e
のみ
components
やconstants
については再ビルド、再テストは不要
依存関係がわからず、意図しない変更が起こるよね?
A. 起こりうる。ただし、ツールを正しく使うことでその可能性は減る
Code Owners
GithubやGitlabにはCODE_OWNERSという機能があり、
以下のような形で権限設定をすることができます
apps/app-a/* @kobori.hikaru
apps/app-b/* @tarou
libs/components/* @kobori.hikaru @tarou
このように設定しておくことで、変更による影響を検知することができる
依存関係の制約
Nx
などのツールでは、メタデータを追加することで、import範囲を絞ることができる
例えば
apps/
└ user-front-sp
└ user-front-pc
└ backend
└ admin
└ sadmin
libs/
└ components
└ user/
└ admin/
└ api-client
└ constants
このような構成になっている際、libs/components/user/*
はadmin
やsadmin
からインポートされることを望んでいない
メタデータを追加しておくことで
このようにエラーを表示させることができる
共通部分で破壊的変更があった場合は影響範囲が広がるよね?
A. 起こりうる
依存関係にあるプロジェクトにおいて、バージョンを複数作るなどして工夫し、古いバージョンから新しいバージョンへの移行をしないといけない
個人的所感まとめ
Good
- リソースの共有
- プロジェクトごとに自由な技術選定、設計
- うまくやれば、ビルド時間を短縮できる
注意しないといけないこと
- リソースの共有範囲
- ツールを使い、きちんと制限すべき
- 設計
- プロジェクトごとにバラバラの設計になる可能性あり
- 依存関係の強いライブラリの初期設定を丁寧にする必要あり
- あとから破壊的な変更が多いとしんどい
Discussion