要点
SharedModuleを卒業する- 関心による分離を原則としてモジュール化する
- 性質で分離しない
- Application と Library のモジュールを分ける
依存関係の原則
- Root と Feature は互いに依存しない
プラクティス
関心による集約と分離
性質ではなく関心の領域によりモジュール化する。 SharedModule ではなく、その中の個別の機能群を個別にモジュール化する。
お手本は Angular Material の MatButtonModule や CDK の LayoutModule など。これにより、Lazy Loading によるコード分割の効果を高められる。
アプリケーション内外の境界
アプリケーションの事情(アプリケーションドメイン)に依存する機能群は app 内に、依存しない機能群は libs 内に配置する。
app/shared ディレクトリに分離されたモジュールも、アプリケーションのコンテキストに依存しない形になったものは、 libs へ昇格できる。
Angular CLI であれば、 libs は ng generate library による multiple projects を利用するのも良い選択である。
Feature Module のフラット化
ファイルツリーが深くなりすぎることを防ぐために、 Feature Module 内にさらに Feature Module を作ることを避ける。(これは中規模におけるプラクティスである)
Routing 管理を分散させすぎず、なるべくフラットに扱う。
Injectable なサービスは原則として root に
@Injectable({ providedIn: 'root' }) により、サービスはどこかで利用されることではじめてバンドルに含められる。
はじめは分散させるよりも root に集約するほうがよいだろう。
Feature Module 内に完全に閉じられるものは閉じてしまっても良い。
ディレクトリ構造の例
src
├ app
│ ├ app.module.ts
│ ├ config
│ ├ domain
│ ├ store
│ ├ queries
│ ├ usecases
│ ├ components
│ │ ├ container
│ │ ├ pages
│ │ └ presenter
│ ├ services
│ │ ├ repositories
│ │ └ ...
│ ├ ...
│ ├ features
│ │ └ admin
│ │ ├ admin-routing.module.ts
│ │ ├ admin.module.ts
│ │ ├ components
│ │ ├ services
│ │ └ ...
│ └ shared
│ └ foo
│ ├ index.ts
│ └ foo.module.ts
└ libs
└ bar
├ index.ts
└ bar.module.ts