← 解説「NgModule — スタンドアロン以前のアプリの骨組み」に戻る
サンプルコードで身につける: NgModule — スタンドアロン以前のアプリの骨組み
解説で学んだ概念を、5つの具体例で確認します。素朴な例から実務寄りの例へと進みます。
14つの配列の役割マップ
NgModuleを読むときに見る場所は実質4つだけです。それぞれの配列が何を意味するかを一枚にまとめます。この地図を持っていれば、大きなモジュールでも迷いません。
// ── @NgModule の読み方マップ ──
//
// declarations: [...] 所有する部品の一覧
// → 「このコンポーネントはどこの所属?」の答えがここ
//
// imports: [...] 借りてくる機能
// → テンプレートで使える部品の供給源。
// CommonModule(*ngIf等) / FormsModule(ngModel) が頻出
//
// providers: [...] DIへのサービス登録
// → 現代は providedIn: 'root' に書く内容の旧居
//
// exports: [...] 他モジュールへの貸し出し
// → ここに無い部品は、他モジュールからは使えない
2「この部品どこから来た?」の追跡手順
テンプレートに知らないコンポーネントが出てきたときの、NgModule時代の探し方です。この追跡ルートは移行中の混在コードでもそのまま使えます。
// テンプレートに <app-user-badge> が出てきた。定義はどこ?
//
// 1. いま読んでいるコンポーネントが standalone か確認
// → standalone なら自分の imports 配列を見る(現代の読み方)
//
// 2. standalone でなければ、自分を declarations している
// モジュール(UserModule など)を探す
// → エディタで 'UserListComponent' を全文検索すると早い
//
// 3. そのモジュールの declarations に UserBadgeComponent があるか
// → あれば同じモジュール所属。定義ファイルへジャンプ
//
// 4. 無ければ imports のモジュールを順に見て、
// exports に UserBadgeComponent を出しているものを探す
3SharedModule と FeatureModule という定番構成
NgModule時代のプロジェクトには決まった構成パターンがありました。名前の付き方に意味があるので、フォルダ構成を見た瞬間に役割を推測できるようになります。
// ── NgModule 時代の典型的な構成 ──
//
// AppModule 起動の起点。bootstrap: [AppComponent] を持つ
//
// CoreModule アプリで1回だけ読み込むもの
// (認証サービス・共通ヘッダーなど)
//
// SharedModule どこでも使う汎用部品の詰め合わせ。
// ボタンやパイプを declarations して
// そのまま exports で貸し出す
//
// UserModule など 機能(feature)単位のモジュール。
// (FeatureModule) 自分のルーティング定義を持つことが多い
//
// → 実務スキル編で学んだ「feature単位のディレクトリ構成」は
// この構成の考え方を standalone 時代に引き継いだもの
4NgModule と standalone の混在コードを読む
移行中のプロジェクトでは両方が同居します。NgModuleがstandalone部品をimportsで借りる形と、standalone部品がモジュールをimportsする形、どちらも合法です。
// パターン1: NgModule が standalone 部品を借りる
@NgModule({
declarations: [LegacyPageComponent], // 旧来の部品
imports: [
CommonModule,
UserBadgeComponent, // ← standalone コンポーネントを直接 imports
],
})
export class LegacyModule {}
// パターン2: standalone 部品が NgModule を借りる
@Component({
selector: 'app-new-page',
imports: [SharedModule], // ← モジュールごと借りて中の部品を使う
template: '...',
})
export class NewPageComponent {}
5bootstrapModule — 起動コードの新旧
main.tsの起動コードも時代で形が違います。既存プロジェクトのmain.tsを見れば、そのプロジェクトがどちらの世代かを一目で判定できます。
// ── 旧: NgModule 時代の main.ts ──
// import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
// import { AppModule } from './app/app.module';
//
// platformBrowserDynamic().bootstrapModule(AppModule);
// → AppModule の bootstrap: [AppComponent] から起動
// ── 新: standalone 時代の main.ts ──
// import { bootstrapApplication } from '@angular/platform-browser';
// import { AppComponent } from './app/app.component';
// import { appConfig } from './app/app.config';
//
// bootstrapApplication(AppComponent, appConfig);
// → モジュールを介さずコンポーネントを直接起動。
// providers は app.config.ts に集まる