要点
-
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