🌊
[TypeScript]モノレポ管理ツール比較検討
モノレポ管理のツールを検討したときのメモ
Background
自分が所属するチームで開発する JavaScript/TypeScript のプロダクトが増えてきて、同じような内容のリポジトリがいくつも存在している(n個とする)。
変更を加えていくにつれて、それぞれの差分が大きくなり、以下のような問題が発生する。
- 開発が止まっているプロジェクトの構成が古くなり、修正コストが発生する
- 開発が複数同時進行している場合、同じような実装を手動で同期する必要がある
これらは共通の基盤等があれば効率的に(理想的にはn分の1の労力で)開発が可能であり、将来的なコストを考えると、いまのうちにその仕組みを考えておきたい。
Proposed Solutions
要件は以下
- 複数のパッケージをnpmとしてpublishできる
- アプリケーションも管理できる
Nx, Rush, Lerna を主要な選択肢としている。
Intro
まず、それぞれの概要をみると何ができるか把握できる。
- Nx | Build full-stack applications with modern tools and reinforce best practices for your entire development team.
- Rush | A scalable monorepo manager for the web
- Lerna | A tool for managing JavaScript projects with multiple packages.
下記の記事でわかりやすく比較されている。
- Rush vs Nx: A Comparison of TypeScript Monorepo Management Tools
- Lerna/Yarn and Nx | Nx Node documentation
- the difference between nx and Lerna ? (monorepos) - Stack Overflow
Nx
概要
- Nrwlという企業が開発している
- (Rush/Nx共通の機能)アプリケーション&ライブラリの管理、影響あるプロジェクトだけrebuild、並列・インクリメンタルビルド、ビルドキャッシュ
- 社内でもすでに実績がある
多くのプラグインがあり、scaffold の機能が Rush に比べると優れている
- Scale your React development with Nx - YouTube
- 新しいライブラリを追加するときは便利かもしれない
- アプリケーションに関してはどこまで活かせるかわからないが、例えば component generator とかもあるので、ある程度レールを敷いたりはできるかもしれない
- このように、アプリケーションストラクチャに対して Opinionated で、開発者体験も良くしようとしているのが Nx の特徴である
Dependency Graph をみることができる。Rushでも内部でDep Graphはあるが、視覚化する機能はない
publish 用にビルドすることはできるが、publish 自体は自分で行う必要がある
- これを考えると、Lernaと併用するのがいいのかもしれない
- 公式では
Setting up some automated script in Nx’s tools folder may also come in handy.
とも言っている - ※将来的にすべてがモノレポで管理されているなら publish する必要もないかもしれないが
node_modules がどうインストールされるかには関与しない
- 特に設定しなければすべてルートにインストールされる
- 不要なパッケージが別のアプリケーションコンテナにも含まれてしまう
- 様々なアプリケーションを管理するなら、やはりLerna等と併用してそれぞれにpackage.jsonを持ったほうが良さそうな気がする
Rush
概要
- マイクロソフトという聞いたことのない企業が開発している(全社的に使われているわけではなく、OneDriveなど一部のチームで使用されているらしい)
- (Rush/Nx共通の機能)アプリケーション&ライブラリの管理、影響あるプロジェクトだけrebuild、並列・インクリメンタルビルド、ビルドキャッシュ
できる。後述のnode_modules の件もそうだが、Node.js 標準・慣習に従いつつ、大規模モノレポへのベストプラクティスを提供している印象
npm の publish が楽にデプロイ時も必要な依存だけ含めてくれる
node_modules をアプリごとにいい感じにDedupingしてくれるのが Nx にはない特徴。- この事情もあり、package manager は pnpm を推奨している雰囲気(npmもyarnも使うことは可能)
- RushのGitHubリポジトリもpnpmで管理されている
- pnpmでは「npmドッペルゲンガー」の問題を解決できる
- しかし、pnpmのsymlinkの仕組みはパッケージによっては非対応なことがあるらしく、自身で対応させる必要があったりするとのこと(
it may seem daunting for a small team
とのこと🤔 詳細はこちら; Rush: NPM vs PNPM vs Yarn) - また、npmは最新バージョンに対応していなかったり(v4系・・・!)、yarnはまだバグが割とある、のように書かれていた
いい感じのChangelogを生成できる( [Changelog tracking](https://rushjs.io/pages/intro/welcome/)
)
Lerna
- アプリケーションというよりは、複数のパッケージを管理することに向いている
- Deduping, npm Task orchestration, Publishing
- 上記2つと比較するとシンプルに導入できる
- yarn workspaces, pnpm, Bolt 等もひとまずこの系統と捉える
検討したがマッチしなさそうなツールたち
Bit
- What is Bit | Bit Docs
- コンポーネントドリブンで多数のアプリケーション開発をマイクロフロントエンド的に行う場合に有効そう
- 今回は、フロントエンド以外でも共通コードを管理したいことから、ユースケースとしてマッチしないかもしれない
Bazel
- Bazelの解説
- JavaScript and Bazel - Bazel main
- モノレポ管理というよりは、複数プロジェクト/パッケージに対してのビルドツール
- モノレポに使うにはいろいろと頑張って整える必要がある(Bazel職人の誕生)
- より巨大なモノレポに対してハイパフォーマンスに並列ビルドしたい、とかなら有効かも
References
- 11 Great Tools for a Monorepo in 2021 | Bits and Pieces
- JavaScript monorepo tools | AGEEK
- npm Blog Archive: Monorepos and npm
- Jared Palmer on Twitter: "Thoughts and experiences on Rush vs. Nx vs. Bazel vs. other monorepo tools for typescript and react repos with a few apps and a bunch of shared private packages?" / Twitter
- LernaとYarn WorkspacesでMonorepo管理 - Cybozu Inside Out | サイボウズエンジニアのブログ
モノレポ Pros / Cons
- Monorepos | Nx React documentation
- Rush: Why one big repo⁈
- Misconceptions about Monorepos: Monorepo != Monolith | by Victor Savkin | Nrwl
Discussion