【Angular】ng generate の便利なオプション

# バージョン

```sh
% ng version
Angular CLI: 13.2.2
```

# 基本構文
```sh
% ng generate <schematic> [options]
```

`<schematic>`には、スキーマ(`module`や`component`)を指定します。



# options

### --dry-run (-d)

実行前に生成、更新されるファイルを確認しておきたいときに。

```sh
% ng generate component test -d
CREATE src/app/test/test.component.scss
CREATE src/app/test/test.component.html
CREATE src/app/test/test.component.spec.ts
CREATE src/app/test/test.component.ts
UPDATE src/app/app.module.ts

NOTE: The "dryRun" flag means no changes were made.
```



### --defaults

対話モードを無効化します。
例えば、`ng generate application`の場合、通常だと
`? Would you like to add Angular routing? (y/N) `や
`? Which stylesheet format would you like to use? (Use arrow keys)`
のように、コマンド入力が必要となりますが、`--defaults`を指定すれば、全てデフォルト設定で自動でやってくれます。



### --module

指定可能なスキーマ：`component` `directive` `module` `pipe`
指定したモジュールの`imports`に自動的に追加されます。

```sh
% ng generate module modules/test --module=app.module.ts
CREATE src/app/modules/test/test.module.ts
UPDATE src/app/app.module.ts
```

<details><summary>app.module.ts</summary><div>

```ts:app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { TestModule } from './modules/test/test.module';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    TestModule // NEW
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
```

</div></details>

指定する文字列は`.module.ts`を省略可能。
`src/app`からの相対パスで指定します。
(例)`src/app/modules/test/test.module.ts`にimportしたい場合

```sh
% ng generate module modules/test2 --module=modules/test
CREATE src/app/modules/test2/test2.module.ts
UPDATE src/app/modules/test/test.module.ts
```



### --export

指定可能なスキーマ：`component` `directive` `pipe`
指定した場合、モジュールの`exports`に追加されます。
`SharedModule`などに含まれるコンポーネントを生成するときに使いましょう。

```sh
% ng generate component test --export
CREATE src/app/test/test.component.scss
CREATE src/app/test/test.component.html
CREATE src/app/test/test.component.spec.ts
CREATE src/app/test/test.component.ts
UPDATE src/app/app.module.ts
```

<details><summary>app.module.ts</summary><div>

```ts:app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { TestComponent } from './components/test/test.component';

@NgModule({
  declarations: [
    AppComponent,
    DefaultComponent,
    TestComponent,
  ],
  imports: [BrowserModule, AppRoutingModule],
  providers: [],
  bootstrap: [AppComponent],
  exports: [TestComponent],
})
export class AppModule {}

```

</div></details>



### --skip-tests

指定可能なスキーマ：`application` `class` `component` `directive` `guard` `interceptor` `pipe` `resolver` `service`
指定した場合、`spec.ts`を生成しません。

```sh
% ng generate component test --skip-tests
CREATE src/app/test/test.component.scss
CREATE src/app/test/test.component.html
CREATE src/app/test/test.component.ts
UPDATE src/app/app.module.ts
```



### --flat

指定した場合、ディレクトリを作成しません。
指定可能なスキーマ：`component` `directive` `guard` `interceptor` `module` `pipe` `resolver` `service`

```sh
% ng generate module modules/test --flat
CREATE src/app/modules/test.module.ts
```



### --routing

指定可能なスキーマ：`application` `module`
指定した場合、同時にルーティングモジュールを作成します。

```sh
% ng generate module modules/test --routing
CREATE src/app/modules/test/test-routing.module.ts
CREATE src/app/modules/test/test.module.ts
```

<details><summary>test.module.ts</summary><div>

```ts:test.module.ts:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { TestRoutingModule } from './test-routing.module';


@NgModule({
  declarations: [],
  imports: [
    CommonModule,
    TestRoutingModule
  ]
})
export class TestModule { }
```

</div></details>

<details><summary>test-routing.module.ts</summary><div>

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

const routes: Routes = [];

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

```

</div></details>



### --route

指定可能なスキーマ：`module`
指定されたパスで遅延ロードするモジュールを生成します。
生成されたモジュールのルートに表示されるコンポーネントと、ルーティングモジュールも同時に作成されます。
遅延ロードさせるモジュールを`--module`オプションで指定する必要があります。

```sh
% ng generate module modules/test --route=hoge --module=app
CREATE src/app/modules/test/test-routing.module.ts
CREATE src/app/modules/test/test.module.ts
CREATE src/app/modules/test/test.component.scss
CREATE src/app/modules/test/test.component.html
CREATE src/app/modules/test/test.component.spec.ts
CREATE src/app/modules/test/test.component.ts
UPDATE src/app/app-routing.module.ts
```

<details><summary>app-routing-module.ts</summary><div>

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

const routes: Routes = [
  // UPDATE
  {
    path: 'hoge',
    loadChildren: () =>
      import('./modules/test/test.module').then((m) => m.TestModule),
  },
];

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

</div></details>

<details><summary>test-routing.module.ts</summary><div>

```ts:test-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { TestComponent } from './test.component';

const routes: Routes = [{ path: '', component: TestComponent }];

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

</div></details>



### --change-detection (-c)

指定可能なスキーマ：`component`
`OnPush`を指定した場合、`ChangeDetectionStrategy.OnPush`で生成されます。

```sh
% ng generate component test --change-detection="OnPush"
CREATE src/app/test/test.component.scss
CREATE src/app/test/test.component.html
CREATE src/app/test/test.component.spec.ts
CREATE src/app/test/test.component.ts
UPDATE src/app/app.module.ts
```

<details><summary>test.component.ts</summary><div>

```ts:test.component.ts
import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';

@Component({
  selector: 'app-onpush',
  templateUrl: './onpush.component.html',
  styleUrls: ['./onpush.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class OnpushComponent implements OnInit {
  constructor() {}

  ngOnInit(): void {}
}

```

</div></details>



### --display-block (-b)

指定可能なスキーマ：`component`
スタイルに`:host { display: block; }`が追加されます。

```sh
% ng generate component test --display-block
CREATE src/app/test/test.component.scss
CREATE src/app/test/test.component.html
CREATE src/app/test/test.component.spec.ts
CREATE src/app/test/test.component.ts
UPDATE src/app/app.module.ts
```

<details><summary>test.component.scss</summary><div>

```scss:test.component.scss
:host {
  display: block;
}
```

</div></details>



# nameの指定方法

例えば`module`の場合、基本構文はこうなります。

```sh
% ng generate module <name> [options]
```

この`<name>`へ指定する文字列は、コマンド実行時のカレントディレクトリによって挙動が変わるため、注意が必要です。

カレントディレクトリがプロジェクトルートの場合は、`src/app`からの相対パスを指定します。
(例)`src/app/modules`に作成する場合

```sh
% ng generate module modules/test
CREATE src/app/modules/test/test.module.ts
```

カレントディレクトリがプロジェクトルート以外の場合は、カレントディレクトリからの相対パスを指定します。
(例)カレントディレクトリが`src/app/hoge`で、`src/app/modules`に作成する場合

```sh
% ng generate module ../modules/test
CREATE src/app/modules/test/test.module.ts
```

ちなみに、指定されたサブディレクトリが存在しない場合（上記の場合`modules`ディレクトリが存在しない場合）は、自動で作成してくれます。


# さいごに
他にも色々なオプションがあるので、一度目を通しておくのがいいと思います。
[Angular公式](https://angular.jp/cli/generate)