結論から
この記事はAngularのプロジェクト開発において、できるだけコンポーネントをモジュール化し、それをimportしていく形でプロジェクト開発していくほうが色々幸せになれるよというお話です。
比較
Angularの開発において大きく分けて2パターンの方法で開発できます。
- パターン1: rootモジュール(lazy loading時のloadChildrenの指定先のようなもの)配下の全てのコンポーネント(孫、ひ孫等含め)をdeclareして使用する
- パターン2: それぞれのコンポーネントをモジュール化し、そのモジュールを直属の親コンポーネントのモジュールにimportする事で使用する。
パターン1
root
├── root.component.html
├── root.component.scss
├── root.component.ts
└── root.module.ts
child
├── child.component.html
├── child.component.scss
└── child.component.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RootComponent } from './root.component';
import { ChildComponent } from '../child/child.component';
@NgModule({
imports: [
CommonModule,
],
declarations: [
RootComponent,
ChildComponent,
],
})
export class RootModule { }
パターン2
root
├── root.component.html
├── root.component.scss
├── root.component.ts
└── root.module.ts
child
├── child.component.html
├── child.component.scss
├── child.component.ts
└── child.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RootComponent } from './root.component';
import { ChildModule } from '../child/child.module';
@NgModule({
imports: [
CommonModule,
ChildModule
],
declarations: [
RootComponent,
],
})
export class RootModule { }
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ChildComponent } from './child.component';
@NgModule({
imports: [
CommonModule,
],
declarations: [
ChildComponent,
],
exports: [
ChildComponent
]
})
export class RootModule { }
上記2パターンで全く同じ結果になるプロジェクトをモノレポで参考として開発してみました。
開発には適度なのソースコードを必要とするため、Angular Materialで紹介されているexample集を集めたものにしています。
パターン2の方が良いとする理由
~example-one/src/app/roots/categories.module.ts
~example-two/src/app/roots/categories.module.ts
上記二つのファイルを比較していただければ一目瞭然ですが、パターン1において
- categories.module.tsに全てのコンポーネントをdeclareしているため、そもそも読みづらくなります
- コンポーネントを削除したい、一部を編集したいとなった場合に不要となるモジュール(今回の場合 Angular Material等)を把握できないので、不使用でimportしてしまうという状況に陥る蓋然性が高くなる。
- lazy loadingを使用し複数のrootモジュールを利用している場合などで、複数のモジュールでコンポーネントを共有する場合、結局そのコンポーネントをモジュール化する事が必要になる。
ビルド結果
ほぼ一緒ですね。
まとめ
パターン1からパターン2への移行は意外と骨が折れます。
因みに、AppModule内で独自モジュールをimportし、且つlazy loadingを利用している場合パターン2への移行時にそこまわりの構成を考え直さないといけなくなります。
パターン1でもプロジェクト開発は進められます。共有するコンポーネントのみモジュール化するという方法でも問題はないでしょう。
しかし、可読性や開発効率等において僕自身はパターン2での開発をおすすめします。