[Angular]MultipleModule構成でのRouting

## 概要

- Angularアプリでモジュールを区切るとモジュール単位でルーティングの設定ができます
- 複数モジュール作るとそれぞれネームスペースを切って疎結合に開発していくことができます
- どのように設定するか試してみたメモです

## 手順

### アプリの雛形作成

- まずはAngularCLIでアプリの雛形を作ります

```zsh
ng new ng-multiple-module-routing-sample --routing=true --skip-tests=true --no-interactive=
```

- `src/app`配下のファイル

```
% tree src/app
src/app
├── app-routing.module.ts
├── app.component.css
├── app.component.html
├── app.component.ts
├── app.module.ts
```

- `app.component.html`の余計なコードを消しておきます

```html:src/app/app.component.html
<router-outlet></router-outlet>
```

### moduleの作成

- homeモジュールを作ります

```zsh
ng generate module --name=home --module=app --route=home --routing --no-interactive
```

- `src/app/home`ができました

```
% tree src/app
src/app
├── app-routing.module.ts
├── app.component.css
├── app.component.html
├── app.component.ts
├── app.module.ts
└── home
    ├── home-routing.module.ts
    ├── home.component.css
    ├── home.component.html
    ├── home.component.ts
    └── home.module.ts
```

- この時点でroutingに関するファイルは`src/app/app.routing.module.ts`と`src/app/home/home-routing.module.ts`の2つできあがっています
- まずは`app.routing.module.ts`を見てみます

```ts:src/app/app.routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  {
    // /home/**へのアクセスはh./home/home.moduleへ飛ばされる
    path: 'home',
    loadChildren: () => import('./home/home.module').then(m => m.HomeModule),
  },
];

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

- `app.routing.module.ts`にはhomeモジュールのルーティングが設定されています
- `/home`から始まるURLにアクセスするとhomeモジュールへのアクセスと判断され`home.routing.module.ts`のルールが適用されます
- `home.routing.module.ts`を見てみます

```ts:src/app/home/home.routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

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

// pathの部分は/homeの後ろの値のこと。つまり''は/homeに該当する
const routes: Routes = [{ path: '', component: HomeComponent }];

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

- `path: ''`へのアクセスが`HomeComponent`にマッピングされています
- これはすなわち、`/home`にアクセスすると`HomeComponent`が表示されるということです
- アクセスすると`home worls!`が表示されます

<img width="425" alt="スクリーンショット 2020-02-03 22.02.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175213/1c1780bb-26a6-0420-583a-9ed978e7d22f.png">

### moduleにルーティングを追加

- homeモジュール内にページを追加してみます
- aboutコンポーネントを作成します

```zsh
ng generate component --name=home/about --module=home --skipTests --no-interactive
```

- `src/app/home/about`ができました

```
% tree src/app
src/app
├── app-routing.module.ts
├── app.component.css
├── app.component.html
├── app.component.ts
├── app.module.ts
└── home
    ├── about
    │   ├── about.component.css
    │   ├── about.component.html
    │   └── about.component.ts
    ├── home-routing.module.ts
    ├── home.component.css
    ├── home.component.html
    ├── home.component.ts
    └── home.module.ts
```

- homeモジュールのroutingにaboutコンポーネントへのマッピングを追加します

```ts:src/app/home/home.routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

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

const routes: Routes = [
  { path: '', component: HomeComponent },
  // /home/aboutにアクセスするとAboutComponentが表示される
  { path: 'about', component: AboutComponent },
];

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

- Aboutコンポーネントへのルーティングを追加しました
- Homeモジュール内のroutingなので`/home/about`にアクセスするとAboutコンポーネントが表示されるというわけです

<img width="364" alt="スクリーンショット 2020-02-03 22.07.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175213/b4a24186-64fe-ab00-ad8d-1619d92255b2.png">

- Homeモジュール内で以下のよなredirectの設定をすると`/home`へのアクセスが`/home/about`へリダイレクトされるといった具合です

```ts
const routes: Routes = [
  { path: '', redirectTo: 'about', pathMatch: 'full' },
  { path: 'about', component: AboutComponent },
];
```

### 注意

- モジュール内のルーティングの設定で`path: '/about'`のように`/`をつけてしまうとうまく動かないので気をつけてください
- これのせいでうまく動かなくてはまりました

### 感想

- 分割したモジュールごとにネームスペースが区切られて疎結合に開発していくことができます
- 規模が大きくなってきた場面で活きてきそうですね