これはHubble Advent Calendar 2024の4日目1の記事です。
はじめに
株式会社Hubbleのフロントエンドを担当している @KOHETs です。
去年のAdvent CalendarでNxを導入した話を書いたのですが、あれから約1年が経ちました。今年は、導入当初からの目標だった 80/20アプローチをついに成し遂げたので、それについて話したいと思います。
正直「いつ終わるんだ?」と思うこともありましたが、やり遂げた今は達成感しかありません。
80/20 アプローチとは
まず、80/20アプローチについて簡単に説明します。
Nxは、アプリケーション(apps)とライブラリ(libs)という2つの要素で構成されています。アプリケーションは複数のライブラリを組み合わせて構築される仕組みです。この構造を利用して、80%のロジックをlibsに集約し、20%のロジックをappsに配置するのが80/20アプローチです。
Nx v18時点の公式ドキュメントに記載されていましたが、現在のドキュメントでは削除されています。そのため、この記事では当時の記述を参考に進めます。
このアプローチの魅力は、コードの再利用性を高め、CIの効率を大幅に向上させる点です。特に、Nxの「影響範囲キャッシュ」と組み合わせることで、必要な部分だけビルドやテストを行うことができるのです。
Nx導入前の状態
2020年当時、Hubbleでは以下のように、独立したリポジトリで開発が行われていました。
-
app1
、app2
、app3
の3つのアプリケーションがそれぞれ別リポジトリで存在。 - 共通コンポーネントを管理するUIライブラリも独立したリポジトリで運用。
一見、リポジトリを分けることで整理されているように見えますが、開発が進むにつれて以下の課題が明らかになりました。
- リポジトリ間でのコードの重複:複数のアプリケーションに共通するロジックが重複し、修正や拡張が煩雑に。
- CI/CDの効率の悪さ:UIライブラリを変更するたびに、各アプリケーションが個別にビルドやテストを実行。
- UIライブラリ提供の手間:npm packageを利用しているため、UIライブラリの変更がアプリケーションに反映されるまでの手間が大きい。
これらの課題を解決するため、「モノレポを導入し、すべてのコードを1つのリポジトリに統合しよう」という決断をしました。
モノレポ統合後の状態
Nxを導入してモノレポに統合した直後のディレクトリ構成は以下のような形でした。
.
├── apps
│ ├── app1
│ │ └── src/app
│ │ ├── feature1
│ │ ├── feature2
│ │ └── shared
│ ├── app2 (app1と同じ)
│ └── app3 (app1と同じ)
└── libs
└── shared
└── ui
これにより、リポジトリ間の分散は解消されましたが、まだ以下の問題が残っていました。
- CI/CDの非効率性:各アプリケーションのテストやビルドがすべて実行される状態は変わらず。
- モジュール化の不足:ライブラリはUIコンポーネントだけに限定され、再利用性の向上には至らず。
80/20アプローチに向けて
モノレポ統合の次に取り組んだのが、アーキテクチャの再設計です。
アプリケーションごとにディレクトリを分け、それぞれの機能を独立したライブラリとして切り出しました。具体的には以下のような構成に変更しました。
.
├── apps
│ ├── app1
│ ├── app2
│ └── app3
└── libs
├── app1
│ ├── feature1
│ ├── feature2
│ └── shared
├── app2 (app1と同じ)
├── app3 (app1と同じ)
└── shared
└── ui
├── button
└── dialog
Angularでは、機能ごとにモジュールを分割する設計が基本となっており、Lazy Loadingによってモジュールが独立した単位で運用されています。この特性を活かし、Feature ModuleをNxのライブラリ構造に移行する際にも大きな変更は必要ありませんでした。
移行作業は、import
パスを変更し、依存関係を明確に整理するだけでスムーズに完了しました。
移行のプロセス
移行作業は一度にすべて行うのではなく、新しいモジュールを作成する際には新構成を適用し、既存のコードは少しずつリファクタリングしました。この柔軟なアプローチにより、日々の業務に支障をきたすことなく進行しました。
Angularや他のライブラリのバージョンアップとも並行していたため、最終的に移行が完了するまでに約4年を要しました。そして2024年11月、すべてのモジュールがライブラリ化され、80/20アプローチを完全に実現しました。
現在の状況
Hubbleの開発規模はこの4年間で大きく拡大し、現在ではアプリケーションが9つ、ライブラリが198個に達しました。このような規模でも、Nxの影響範囲キャッシュ機能を活用することで、効率的な開発体制を維持しています。
現在のCIの実行時間もワーストケースでは30分以上かかってしまいますが、平均11分で完了するようになりました。さらに、コードのモジュール化が進んだことで、可読性やメンテナンス性も向上しました。
まとめ
この記事では、HubbleがNxを活用して80/20アプローチを達成するまでの道のりを紹介しました。モノレポ導入からアーキテクチャの再設計、移行作業、そして現在の成果まで、チーム全体の努力の結晶です。
似たような課題に直面している方にとって、この経験が少しでも参考になれば嬉しいです。もし興味が湧いたら、ぜひチャレンジしてみてください!
明日は @beltway7 さんです!
-
平日のみの投稿なので5日ですが、4日目の記事としています。 ↩