モノレポって結局どうなの？という話

## はじめに

リンクアンドモチベーションでフロントエンドエンジニアをしている菊池です。
私は業務で2つのモノレポを開発・運用しているのですが、1年ほど運用してみて「結局モノレポにするメリットはなんだろう」というのを自分なりにまとめたいと思います。

モノレポのメリットやツールは[Monorepo Explained](https://monorepo.tools/)という素晴らしいサイトにまとまっているのですが、実際に運用して肌で感じたことを備忘として残したいと思います。

https://monorepo.tools/

私が主にフロントエンドを専任しているため、フロントエンド寄りかつ個人の意見になりますが、これからモノレポを検討している人の参考になれば幸いです。

この記事は[モチベーションクラウドシリーズ Advent Calendar 2022](https://qiita.com/advent-calendar/2022/mcs)の11日目の記事です。

## メリットだと思うこと

### 1. フローが一元化される

個人的に最も大きなメリットだと思っているのが、管理対象リポジトリが1つであることによるフローの一元化です。

リポジトリが複数ある場合、それぞれでルールとフローを整備する必要があります。
フロントエンドだと、アプリケーションの開発は以下のフローになることが多いと思います。

- 実装
    - Lint
        - ESLint
    - フォーマット
        - Prettier
- テスト
    - 単体テスト
    - 結合テスト
    - E2Eテスト
    - etc...
- デプロイ
    - デプロイ関連のスクリプト等

ESLintやPrettierなどの実装ルールは１つの設定ファイルに過ぎないので、正直別リポジトリでも合わせるのは容易です。また場合によってはパッケージごとにルールを変えたいケースもあるので、モノレポでもあえて統一しなくても良いと思っています。

一方でテストやデプロイの仕組み（およびCI/CD）は基本同じであることが多く、ここはモノレポで統一させて楽だったと感じました。もし小さなパッケージごとに別リポジトリだったらかなり大変だったと思います。

またコードオーナー（テックリード）目線でも、フローが散在しないので「あっちのリポジトリでは直したけどこっちで忘れてた、、」みたいなことがなく、同じリポジトリだけ注力して管理すればいいので、フローを厳格に縛りたいけど管理できるテックリードが少ない場合には方法としてマッチすると思いました。

## 難しいと感じたこと

### 1. レールに乗せるまでの管理コストと難易度が高い

これは当然っちゃ当然なんですが上手くいく仕組みを整備するまでが結構大変です。
モノレポじゃなくてもそうじゃないか？と思うかもしれませんが、モノレポ特有のあれやこれ（後述）もあるため、色々と調整が必要になることが多かったです。

なお、[Nx](https://nx.dev/)や[Lerna](https://lerna.js.org/)などを使うことで楽になる箇所はあります。
ただこれらのツール自体の選定も必要になるため、そういう意味で固有の難しさがあると感じました。

### 2. ライブラリの依存解決が難しい（ことがある）

ライブラリの管理にYarnを使っていますが、あるアプリケーションAだけで特定のライブラリをインストールしようとするとエラーになる場面がよくあります。
これはほとんどの場合ライブラリの依存が噛み合わないことに起因します。

Yarnの[nohoist](https://classic.yarnpkg.com/blog/2018/02/15/nohoist/)や[Selective dependency resolutions](https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/)でなんとかすることが多いですが、中々歯ごたえのある調査が必要になることがあります。

（[Storybookみたいな多数のフレームワーク対応をモノレポで管理](https://github.com/storybookjs/storybook/tree/v7.0.0-beta.3/code/frameworks)してるの見ると、すごいな、、と思います）

### 3. IDEの拡張が動かない（ことがある）

コーティングにVSCodeを使っていますが、拡張機能によってはモノレポでは動かない拡張もあります。
というのも、拡張機能はデフォルトでは設定ファイルをリポジトリルートから探すことが多く、モノレポ構成だとうまく見つけられないことがあります。

このような場合は、VSCode自体を対象アプリケーションのディレクトリから開くか、VSCodeのWorkspacesのfolders設定でそれぞれをルートとして開くことで動くことがあります。

```json:sample.code-workspace
{
	"folders": [
		{
			"name": "sample/root",
			"path": "."
		},
		{
			"name": "sample/pkg-a",
			"path": "./pkg-a"
		},
		{
			"name": "sample/pkg-b",
			"path": "./pkg-b"
		},
	],
	"settings": {}
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939205/3c805715-d8aa-5768-412d-7f94061bcbe8.png)


### 4. エコシステムが若干絞られる

[LernaとGithub Actionsでmonorepoライブラリのリリースを楽にする](https://link-and-motivation.hatenablog.com/entry/2022/11/16/190305)で、リリースフローを検討したとき、モノレポ対応に絞るとツールが多少制限されました。

https://link-and-motivation.hatenablog.com/entry/2022/11/16/190305#%E3%83%84%E3%83%BC%E3%83%AB%E3%81%AE%E9%81%B8%E5%AE%9A

一方でデプロイやホスティングに関しては、[Netlify](https://docs.netlify.com/configure-builds/monorepos/)や[Vercel](https://vercel.com/docs/concepts/monorepos)などは標準対応しており、プラットフォームレベルだとモノレポ対応まで考慮されているソフトウェアが多い印象です。

## おわりに

難しいことが多くなってしまいましたが、実際モノレポ管理は「難易度は高い」と思っています。
ただこれはモノレポを選定した後の難しさの話で、モノレポを選定しない理由ではありません。

上記の問題を超えて、ある程度安定した今はモノレポのメリットを感じています。
今後もモノレポ界隈をウォッチして、開発を便利にする仕組みを導入していきたいと思います。