Angular のルーティングにおける children と loadChildren の違い

Angular のルーティングで階層を作りたい時、children で定義する方法と、loadChildren でルーティングモジュールを含んだ子モジュールを文字列で指定する方法があり、違いを調べてみた。

children を使った実装方法

通常は children で階層を作ることが多いだろうか。

home-routing.module.ts

ルートモジュールの app-routing.module.ts では特に実装せず、子モジュールの ./src/app/home/home-routing.module.ts でルーティングを定義する。

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { HomeComponent } from './home/home.component';

const routes: Routes = [
  {
    // 「home/」以下の URL を定義する
    path: 'home',
    children: [
      // コレで「home/my-home」という URL になる
      { path: 'my-home', component: HomeComponent },
      // 必要ならリダイレクト設定とか…
      // { path: '', redirectTo: '/home/my-home', pathMatch: 'full' }
    ]
  }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class HomeRoutingModule { }

コレだけ。

loadChildren を使った実装方法

先程の children の場合と同じ動作にするには、以下のように実装できる。

app.routing.module.ts

まずはルートのルーティングモジュール。ココで loadChildren を指定する。home.module.tsHomeRoutingModule 等を含んだ NgModule だ。

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

const routes: Routes = [
  // 「/home」にアクセスした時 HomeModule を読み込む
  { path: 'home', loadChildren: 'app/home/home.module#HomeModule' }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

home-routing.module.ts

次に HomeRoutingModule。ココは children プロパティの内部に相当する指定があれば良い。

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { HomeComponent } from './home/home.component';

const routes: Routes = [
  // AppRoutingModule での設定により「''」で「/home」というパスになる
  // コレで「/home/my-home」となる
  { path: 'my-home', component: HomeComponent }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class HomeRoutingModule { }

childrenloadChildren の違い

childrenloadChildren は何が違うのか。実装の仕方が異なるのは勿論だが、loadChildren の方は読み込むモジュールを文字列で指定していたりして、何だか違和感がある。

コレは何かというと、loadChildren で書いたモジュールは遅延読込されるようなのだ。たまにしか読み込まないモジュールなどは起動時に全読み込みしておく必要がないので、こうして Lazy Load させる、というワケ。