Angular6のプロジェクトを作ったらまずやっとくこと

# はじめに

最近立て続けにAngular6のプロジェクトを作ったので、最初にやっておく作業をメモしておきます。
あくまで自分が作るときにやってることで、全てが誰にでもオススメってわけじゃないです。

追記: Angular7 のプロジェクトもこれでいけました。

# yarn使う設定にしておく

自分はグローバルで Angular がパッケージマネージャに yarn 使う設定にしてます。
（最近の npm は進化したので最早 yarn を使うメリットはないかも。npm 使うならこの記事の yarn の部分は全て npm に置き換えてください。）

```
ng config -g cli.packageManager yarn
```

# プロジェクト作成

プロジェクト作る時には

 - SCSS使う設定をしておく
 - ルーティング設定ファイルも作成しておく

指定をします。
なおプロジェクト名の単語区切りはアンダーバーだとエラーになるのでハイフンで。"management-3d-data"とか単語の頭が数字なのもダメみたいです。

```
ng new my-project --style=scss --routing
```

# TSLintとPrettierの設定

フォーマッターにPrettierを使い、保存時に自動フォーマットされるようにしたい。

フォーマッターの設定とリンターの設定に違いがあると、

　1. リンターに怒られてるところを直す
　2. 保存したら勝手にフォーマットされる
　3. またリンターに怒られる

という悲しい事態になります。

そこで設定を合わせる必要があるのですが、それ以前にPrettierをいつどこで実行させるかという選択肢がいくつかあります。
自分の選択は「TSLintにやらせる」です。

```
yarn add --dev prettier tslint-config-prettier tslint-plugin-prettier
```

tslint.jsonを編集します。以下にdiffを示します。

```diff
 {
   "rulesDirectory": [
-    "node_modules/codelyzer"
+    "node_modules/codelyzer",
+    "node_modules/tslint-plugin-prettier"
   ],
+  "extends": ["tslint:latest", "tslint-plugin-prettier", "tslint-config-prettier"],
   "rules": {
+    "prettier": [
+      true,
+      {
+        "singleQuote": true
+      }
+    ],
+    "no-submodule-imports": false,
+    "interface-name": [true, "never-prefix"],
     "arrow-return-shorthand": true,
```

シングルクォートを使うかどうかをAngularプロジェクト生成時のTSLint側の設定に合わせました。
ついでに

 - インターフェース名の頭にIをつけない（デフォルトでは付ける）
 - サブモジュールのインポートを認める

ように変更しています。

インターフェース名のIプリフィクスは「どっちでもいい」設定にしても良かったかも。マイクロソフトのTypeScript開発チームのルールは「付けない」なのだそうです。

サブモジュールのインポートはAngular自体を使う時に行うことがあるので認めておきます。
それかサブモジュールインポートせざるを得ないものだけ認めるように設定を都度追加する方針にするか（最初そうしてたけど面倒臭くなってやめました）。

追記:
最近作成した Angular 7 プロジェクトでは ```"no-submodule-imports": false,``` は追記する必要はありませんでした。
一応 VSCode 以外を使う人のことも考慮して TSLint 経由で Prettier 実行してたんですが、最近はプロジェクトメンバーみんな VSCode 使うので、VSCode の Prettier プラグインにやらせてます。
その場合は prettier だけインストールして tslint.json に連携設定は書かず、.prettierrc ファイルに ```{ "singleQuote": true }``` を書いておきます。

# コンパイルオプションの設定

tsconfig.json のdiffを以下に示します。
strictNullChecksは絶対に設定しておきましょう。これを設定しないとTypeScriptを使う意味が半減です。

```diff
     "experimentalDecorators": true,
+    "strictNullChecks": true,
+    "noImplicitAny": true,
+    "noImplicitThis": true,
+    "noImplicitReturns": true,
+    "noUnusedLocals": true,
+    "noUnusedParameters": true,
     "target": "es5",
```

厳しくしすぎると開発中にちょっとやりすぎで鬱陶しいと感じることもあります。
例えば一時的にコードをコメントアウトしたときに、noUnusedLocals とか noUnusedParameters とかに引っかかってコンパイルエラーになってしまって、他にも色々コメントアウトしなきゃいけなくなったり。
その辺りはコンパイルオプションでは設定せずに、TSLintで警告してもらうだけに設定した方が開発しやすいかもしれません。

追記:
以下のように tslint.json にルールを追記して、コンパイラオプションに noUnusedLocals と noUnusedParameters を指定するのをやめました。
これで noUnusedLocals と noUnusedParameters で引っかかる部分を TSLint が警告してくれます。が、コンパイルは通ります。

```
  "rules": {
    ...
    "no-unused-variable": [true, {"ignore-pattern": "^_"}],
```

さらに追記:
TypeScript 2.9 から TSLint に上記の設定をすると deprecated だと言われます。コンパイラオプションを使えと。

# Visual Studio Codeの設定

Visual Studio Code（以下VSCode) は .vscode ディレクトリにプロジェクト固有の設定を入れておくことができます。

まず他のメンバーにも入れて欲しい推奨VSCode拡張を、.vscode/extensions.json に設定しておきます。
自分は以下を設定しています。

```json
{
  "recommendations": [
    "mikael.angular-beastcode",
    "angular.ng-template",
    "johnpapa.angular2",
    "joelday.docthis",
    "eg2.tslint",
    "dskwrk.vscode-generate-getter-setter",
    "glen-84.sass-lint",
    "formulahendry.auto-rename-tag",
    "christian-kohler.path-intellisense",
    "michelemelluso.code-beautifier",
  ]
}
```

次にVSCodeの設定のうち、プロジェクト設定を .vscode/settings.json に記載します。

```json
{
  "editor.insertSpaces": true,
  "editor.tabSize": 2,
  "editor.detectIndentation": false,
  "editor.renderControlCharacters": true,
  "editor.formatOnSave": true,
  "editor.formatOnPaste": true,
  "[typescript]": {
      "editor.formatOnSave": false,
      "editor.formatOnPaste": false
  },
  "tslint.enable": true,
  "tslint.run": "onType",
  "tslint.autoFixOnSave": true
}
```

ユーザー設定よりこちらが優先されますので、このプロジェクトに関わる全員に共通で設定しておいて欲しいことをここで指定します。
例えば普段は editor.tabSize を 4 に設定していたとしても、このプロジェクトでは 2 が適用されます。

この設定では TypeScript も HTML も SCSS も全てインデントが 2 で空白に展開するようにしています。
この辺りは言語によって変えたいとか、好きに設定してください。

TypeScriptだけは editor.formatOnSave, editor.formatOnPaste を false にして、保存時やペースト時のフォーマットが走らないようにしています。
これはフォーマッタには Prettier を利用したくて、しかもそれを TSLint にやらせているためです。
保存時に TSLint の自動Fixが走って、その際に TSLint が Prettier を実行してフォーマットされます。

追記:
VSCode の Prettier プラグインにフォーマットさせる場合は、上記の [typescript] の所の設定は削除します。
また .vscode/extensions.json の recommendations に "esbenp.prettier-vscode" を追加しておきましょう。

# ユーティリティスクリプト作成

自分の場合はコンポーネントは src/app/components の下に、サービスは src/services の下に作ってます。
（モジュール分割していない場合はですが）

```ng g component components/hoge``` とか ```ng g service ../services/fuga``` とか、打つのが面倒なのでユーティリティスクリプトを用意しておきます。

```sh:ngc.sh
#/bin/sh
yarn run ng generate component components/$1
```

```sh:ngs.sh
#/bin/sh
yarn run ng generate service ../services/$1
```

```yarn run``` を頭につけているのは、```@angular/cli``` をグローバルにインストールしていなくても動作するようにするためです。
作成済みのプロジェクトをリポジトリから取ってくるプロジェクトメンバーの中には、グローバルにインストールしたくない人もいるかもしれません。

これで、

```
./ngc.sh hoge
```

で HogeComponent が作成され、

```
./ngs.sh fuga
```

で FugaService が作成されます。

# まとめ

Angular6のプロジェクト作ったら、とりあえずこれだけ設定するというのをメモしておきました。
また増えたり減ったり変更するかもしれません。

これを見た人が、自分なりのプロジェクト設定を最初に行う参考になればと思います。