【ITニュース解説】Building Scalable Enterprise Angular Applications with Nx
2025年09月10日に「Dev.to」が公開したITニュース「Building Scalable Enterprise Angular Applications with Nx」について初心者にもわかりやすいように丁寧に解説しています。
ITニュース概要
古いAngularアプリを段階的に新しくするため、Nxと機能指向設計を使う方法を紹介。アプリの機能を独立した部品(ライブラリ)に分け、再利用可能にする。これにより、顧客ごとのカスタマイズや将来的なマイクロフロントエンド化にも柔軟に対応でき、開発・配布が効率化される。
ITニュース解説
現代のソフトウェア開発において、特にエンタープライズ(企業向け)アプリケーションは、時代遅れの技術や複雑に絡み合ったコード、そして増え続ける顧客の要望といった課題に常に直面している。既存システムを全面的に作り直すことは、非常に大きな費用とリスクを伴い、かといって古いシステムをそのまま使い続けるだけでは、新しい技術を取り入れたり、ビジネスの革新を進めたりすることが難しくなる。このような状況を打破し、既存のシステムを現代の技術で改善していく「モダナイゼーション」が多くの企業で求められている。
ここでは、ソフトウェア開発会社「Acme Corp」が提供する「Acme Case Management」というシステムを例に、モダナイゼーションの手法を解説する。このシステムは、ケースの作成と管理、タスクのレビューと割り当て、ユーザー管理、役割や権限設定といった主要な機能を備える。しかし、アプリケーションは10年以上前の技術(AngularJS 1.x、jQueryなど)で構築されたレガシーなモノリス(一枚岩)型のシステムであり、コードが密接に結合しているため、保守や機能拡張が極めて難しいという問題を抱えていた。Acme Corpの目標は、このアプリケーションを現代化し、より柔軟なアーキテクチャへと改善することにある。
Acme Corpは、既存の多くの顧客が利用しているレガシーなモノリスアプリケーションを継続してサポートする必要があるため、全てを一度に書き換えるのではなく、段階的に改善していくことを目指している。具体的には、既存のコンポーネントを最新のAngularやWebコンポーネントで構築された新しいものに置き換えたり、新機能を追加したりして、徐々にシステムを現代化していく方針だ。これにより、既存顧客へのリスクを最小限に抑えつつ、スムーズな移行を実現しようとしている。
また、Acme Case Managementは、医療や政府機関など、さまざまな分野のクライアントに提供されており、それぞれのドメイン(分野)に適したバージョンが必要とされている。コアとなる機能は共通しているものの、特定の機能は修正されたり、新しい機能が追加されたりすることが求められる。さらに、クライアント固有のカスタマイズも重要な要件だ。例えば、特定のクライアントは独自のレポート機能や新しい言語サポートを必要とし、別のクライアントは既存のタスク管理モジュールに添付ファイル機能を加えたいと考えているかもしれない。さらに、あるクライアントは、ケース、タスク、ユーザー管理用のアプリケーションと、管理者用のアプリケーションを別々にしたいという要望を持つ場合もある。これらの多様なニーズに応えるためには、システムが非常に柔軟である必要がある。
システムを顧客に配布する方法も課題の一つである。一部のクライアントはAcme Corpのインフラを利用してアプリケーションを構築・デプロイするが、セキュリティポリシーなどの理由で、独自のビルド・デプロイプロセスを持つクライアントもいる。そのため、Acme Corpは、ライブラリやアップデートを全てのクライアントにスムーズかつ安全に配布できる仕組みを確保しなければならない。さらに将来的な計画として、Acme CorpはアプリケーションをSaaS(Software as a Service)として提供することも視野に入れており、クライアントがアプリケーション全体を再構築することなく、実行時に新しい機能を追加できるような、マイクロフロントエンドアーキテクチャの導入を検討している。
これらのビジネス要件をまとめると、Acme Corpは「同じコア機能に基づいて多様なモノリスアプリケーションを構築できること」「コア機能の一部をWebコンポーネントとしてレガシーや他のアプリケーションに組み込めること」「将来的にマイクロフロントエンドアーキテクチャへ移行できること」「既製のコンポーネントとカスタムコンポーネントを組み合わせたり、既存のものを変更・削除したりできること」「最小限の労力でコードを効率的に配布できること」が必要となる。
これらの複雑な要件を満たすために採用されたのが、「フィーチャー指向アーキテクチャ」と「Nx」を組み合わせた解決策である。フィーチャー指向アーキテクチャとは、アプリケーションの機能を「ケース」「タスク」「管理」といった具体的なビジネス機能ごとに、独立した再利用可能な小さな部品(ライブラリ)に分割して開発する手法を指す。これにより、各機能が互いに影響し合うことなく開発・保守できるようになる。また、これらの機能ライブラリが共通して利用する「UIコンポーネント」「認証」「権限管理」といった汎用的なロジックは、「コアライブラリ」として別に用意される。
Nxは、このような大規模なアプリケーション開発を効率的に管理するためのモノレポ(複数のアプリケーションやライブラリのコードを一つのリポジトリで管理する手法)ツールである。Nxを使うことで、複数のAngularアプリケーションやライブラリを一つのワークスペース内で統合的に管理し、ビルドやテストなどの開発プロセスを効率化できる。例えば、npx create-nx-workspace acme --preset=angular-monorepoというコマンドを実行することで、Angularアプリケーションとライブラリを管理するためのNxワークスペースが作成される。
プロジェクトの構造としては、大きく分けて「アプリケーション」と「ライブラリ」がある。アプリケーションは実際にユーザーが利用する最終的なプロダクトであり、Acme Corpのメインアプリケーションや政府機関向けのバージョン、医療機関向けのバージョン、さらにはマイクロフロントエンドのホストアプリケーションなどが該当する。一方、ライブラリは、これらのアプリケーションを構成する部品となる。ライブラリには、フィーチャーライブラリ(ビジネス機能)、コアライブラリ(共通要素)、テーマライブラリ(デザイン)、Webコンポーネント(レガシー統合用)、拡張ライブラリ(ドメイン特化)といった種類がある。これらのライブラリは、共通の命名規則に従って管理される。例えば、コアライブラリは@acme/core-ui、フィーチャーライブラリは@acme/feature-tasksといった形で、それぞれの役割を示すプレフィックスが付けられる。また、コンポーネントやサービスの名前にもAcmCasesListComponentのように、それがAcmeの標準機能であることを示すプレフィックスが付与される。この命名規則は、数多くの要素が存在する大規模なプロジェクトにおいて、開発者がコードの役割を素早く理解し、管理しやすくするために非常に重要である。フィーチャーライブラリは互いに独立しているべきであり、特定の機能が別の機能に直接依存しないようにすることで、柔軟なカスタマイズや変更が可能になる。
ライブラリの内部構造は、機能ごとにコンポーネント、サービス、データモデルといった要素が整理されて配置される。例えば、「ケース」というフィーチャーライブラリの中には、ケースの一覧表示コンポーネント、ケースに関連するデータモデル、ケースを操作するサービスなどが含まれる。コンポーネントが利用する設定ファイルや多言語対応のための翻訳ファイルなどの「アセット」は、そのコンポーネントのすぐ近くに配置することで、管理のしやすさを向上させている。
新しいライブラリを作成する際には、Nxが提供するジェネレーターコマンドを利用する。例えば、npx nx g @nx/angular:library libs/feature/cases --publishable ...というコマンドを実行することで、「ケース」機能のライブラリが自動的に作成される。このコマンドには--publishableオプションでNPMパッケージとしての配布可能性を、--tags=featureオプションでライブラリの種類を定義する。このタグは、Nxが提供するモジュール境界の強制機能と連携し、異なる種類のライブラリ間での不適切な依存関係が発生するのを防ぐ役割を果たす。
作成されたライブラリをクライアントに配布する標準的な方法は、NPM(Node Package Manager)パッケージとして公開することである。企業内での利用の場合、公開NPMレジストリだけでなく、NexusやVerdaccioのようなプライベートなNPMレジストリを利用することも可能だ。これにより、異なるクライアントプロジェクト間でライブラリをスムーズに統合し、バージョン管理を行うことができる。ライブラリが他のライブラリや外部パッケージに依存している場合、その依存関係をNPMパッケージのpackage.jsonファイル内のpeerDependenciesセクションに正確に定義する必要がある。これにより、ライブラリを利用するアプリケーション側で必要な依存関係が自動的にインストールされるようになる。このプロセスは、NxのESLintルールである@nx/dependency-checksを利用することで自動的にチェックされ、不足している依存関係を特定したり、修正したりすることが可能だ。
ライブラリのバージョン管理も重要である。セマンティックバージョニング(SemVer)というルールに基づいて、バージョンの数字が持つ意味を明確にする。現在のAcme Corpのプロジェクトでは、全てのライブラリが同時に更新されることが多いため、全てのライブラリで同じバージョン番号を使用する「ロックステップバージョン管理」が採用されている。これは、バージョン管理を簡素化し、ライブラリ間の互換性を確保するのに役立つ。しかし、将来的にマイクロフロントエンドアーキテクチャを導入し、個々のライブラリが独立して更新されるようになる場合は、それぞれのライブラリが独自のバージョンを持つ「独立バージョン管理」に切り替えることも可能だ。
各ライブラリに含まれる国際化リソースや設定ファイルなどの「アセットファイル」も適切に管理し、最終的なアプリケーションに含める必要がある。多数のアセットファイルを持つライブラリの場合、アプリケーションのビルド設定ファイルに全てを個別に記述するのは非効率的になるため、Nxのカスタムビルドタスクを利用して、ビルド時にライブラリのアセットを自動的にアプリケーションにコピーする仕組みを導入することで、管理の手間を大幅に削減できる。
Webコンポーネントの作成自体は比較的容易だが、その配布には特別な配慮が必要となる。特に、レガシーなビルドツールを使用しており、CDN(Contents Delivery Network)サーバーの利用が難しいセキュリティ要件を持つクライアントに対しては、WebコンポーネントをNPMパッケージとして配布し、クライアントのビルドプロセスでインストールしてもらう方法が最も適している。
将来的なSaaS化を見据えた「マイクロフロントエンド」アーキテクチャの導入も、この設計アプローチで実現可能だ。マイクロフロントエンドは、アプリケーションを「ケース管理」「タスク管理」といった、さらに小さな独立した部分に分割する手法である。これにより、各マイクロフロントエンドを独立して開発、デプロイ、保守できるようになる。Nxでは、各マイクロフロントエンドごとにアプリケーションを生成し、これらのアプリケーションがフィーチャーライブラリで定義されたビジネスロジックを読み込むラッパーとして機能する。SaaSやマルチテナントのシナリオでは、クライアントが実行時に機能を追加できるような動的な構成が必要となるため、マイクロフロントエンドが最適な解決策となる。
結論として、フィーチャー指向設計とNxモノレポを採用することで、Acme Corpはレガシーアプリケーションの現代化を段階的に進めることができる。機能を小さな独立した部品として捉え、クリーンなアーキテクチャ原則に従うことで、各ライブラリは独立性を保ちつつ保守しやすくなる。このアプローチにより、様々な機能を組み合わせてモノリスアプリケーションを構築したり、NPMパッケージやWebコンポーネントとして配布したり、さらにはマイクロフロントエンドとして組み立てたりと、クライアントの要件や将来のアーキテクチャに柔軟に対応できる基盤を確立できるのである。