monorepo

Monorepoについて

More than 1 year has passed since last update.

Monorepoとは何か

npmで管理する複数のpackageを、まとめて一つのgitリポジトリで管理すること。

具体的に

例えば、 npm上にBabelは108以上のパッケージがある

babel: Babel is a compiler for writing next generation JavaScript. 2017-08-01 22-21-41.png

@loganfsmyth 2017-08-01 22-19-04.png

babelはpluginを追加していくスタイルなので、
babel-core, babel-cli, babel-preset-es2017, babel-preset-flow ....
と、たくさんのパッケージがあり npm install babel-preset-flow 等々して取り込んでいく。

従来、npmでは「1リポジトリ=1パッケージ」が標準だったが、多数パッケージを管理するBabelのようなプロジェクトでは多数リポジトリを扱うことになり、混乱が大きい。

そこで、単一リポジトリの /packages 以下にたくさんパッケージを作り(フォルダとpackage.jsonを多数作り)、管理するのがMonorepo。

これ以上は 実際のBabelのpackagesディレクトリ を見たほうが早い。

babel 2017-08-01 22-20-28.png

単一リポジトリの中に多数のパッケージがあるのがわかると思う。

使用しているプロジェクト

Babel, React, Meteor, そして Ember などが採用。
基本的には多数パッケージを扱う巨大フレームワークが採用しているわけですね。

何が利点か

Why is Babel a monorepo によると

利点:

  • 統一された lint, build, test, release プロセス。
  • モジュールを横断した変更が容易。
  • issueを上げる場所がひとつ(のため見落としがすくない)
  • 開発環境を立ち上げるのが簡単。(100のリポジトリで、個別に100個の開発環境を整備するために100回 npm install と考えるだけで・・Oops)
  • モジュールを横断するテストを走らせるのが容易で、それはつまり複数モジュール環境で起きるバグを見つけやすくなる。

欠点:

  • コードが必要以上に威圧的になっちゃう
  • gitリポジトリが肥大化
  • npmの検索結果で低く表示される。(npmはテストのコードカバレッジを計測しているが、monorepoは個別パッケージでテストしてないのでカバレッジが低くなるため)

僕も/私も使うべきか

規模によっては使用することも考えて良い。
SPAで、フロント・サーバサイド・両者共通機能パッケージ(model関連など)幾つか…と3-10個程度のが存在するときに、
両者共通機能パッケージをmonorepoとし、例えばサーバサイドに寄生させてもいいかもしれない。

ただし、十分に小さく独立性があまりない機能セットの場合、無意味なパッケージ分割は単に混乱を生むだけである。どういう単位で分割するのが良いかはアーキテクチャ・設計なのでよく考えよう。