Angular2 の angular-cli で、webpack の設定を変更して pug(Jade) を使う

# angular-cli
Angular2 触ってみたいけど gulp のスクリプトガリガリ書いたりなんか設定とか難しいんでしょ…？と思っていましたが、angular-cli を使えばコマンド一発でプロジェクトの雛形(Angular + TypeScript + css/less/sass/stylus + html)を作ってくれて、５分で初められるじゃない？というくらい便利になっていました。
ただ、angular-cli では雛形作るところまでやって、あとはカスタムスクリプトという記事も見かけたので、 angular-cli で pug を追加してビルドする手順を書いておきます。（2017/02/25時点）

## pug(Jade) 導入について
html を爆速で簡単に書けるテンプレートエンジンです。Angular2 (Angular) ではコンポーネント志向が徹底しているので、長い html を書くことはあまりないかもしれませんが、ちょっと凝ったことをすると html はすぐに辛くなるので導入することにしました。
[pug](https://pugjs.org/api/getting-started.html)


## angular-cli 導入
みんな大好き npm でインストールしようかと思ったのですが、最近は yarn がキてるっぽいので yarn で導入してみました。使い方は npm とほとんど変わらず簡単で、高速に動作していました。

```
# yarn インストール
> npm i -g yarn

# angular-cli インストール
> yarn global add angular-cli
```

## サンプルプロジェクト作成と、webpack.config.js 抽出
内部で webpack でビルドしているので、webpack.config.js を修正して pug を追加したいのですが、見当たりません。設定を変更せず使いたい人を混乱させないように隠蔽をしたのでしょうか。
抽出するための eject コマンドが用意されているのでそれを呼び出します。

```
# hello-world プロジェクト作成
> ng new hello-world

# webpack.config.js を抽出(ng eject)
> cd hello-world
> ng eject
```

プロジェクトのルートに、webpack.config.js があるか確認しておきます。

```
hello-world/
|.angular-cli.json
|.editorconfig
|.gitignore
|karma.conf.js
|package.json
|protractor.conf.js
|README.md
|tslint.json
|yarn.lock
|webpack.config.js ★ ここに抽出されます
+node_modules/
+e2e/
+src/
```

## webpack, webpack-dev-server をインストール
デフォルト設定で使用する際はこの手順は不要ですが、eject したプロジェクトでは webpack が別途必要になるのでインストールしておきます。

```
> yarn add webpack-dev-server --dev
> yarn add webpack --dev
```

ここで、プロジェクトが正常に動くか一度確認しておきます。

```
> yarn start
```

webpack でビルドされて、ブラウザで http://localhost:8080 などを開いてページが表示されれば正常に動作しています。

## webpack.config.js を修正、pug-html-loader をインストール

module / rules に、 (pug|jade) の設定を追加します。

``` webpack.config.js
...
module.exports = {
...
  "module": {
    "rules": [
      ...
      {
        "test": /\.json$/,
        "loader": "json-loader"
      },
      // ★追加。拡張子が、pug|jade なら、pug-html-loader を利用
      {
        "test": /\.(pug|jade)$/,
//        "loader": "pug-html-loader"  // 2017/05/20修正。コメント頂きました。raw-loader も必要かも？
          "loader": ['raw-loader', 'pug-html-loader'] // 'raw-loader' が必要
      },
      {
        "test": /\.html$/,
        "loader": "raw-loader"
      },
```

pug-html-loader は angular-cli に含まれていないので、インストールします

```
> yarn add pug-html-loader --dev
```

## pug ファイルをビルドしてみる
以下のファイルがデフォルトで生成されているので、html ファイルを pug ファイルにリネームして、中身を pug に書き換える、html を参照していた ts ファイルも、pug を参照するように修正


* src 以下のフォルダ構成

```
src/
+app/
  app.component.css
  app.component.html    # ★ .html -> .pug にリネーム
  app.component.spec.ts
  app.component.ts
```

* .html の中身

```app.component.html
<h1>
  {{title}}
</h1>
```

* .pug にして、中身も書き換える。

```app.component.pug
h1
  | {{title}}
```

```app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.pug',  // ★ .html -> .pug にリネーム
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app works!';
}
```

css については、拡張子を書き換えるだけで less/sass/scss/stylus が使用可能です。

また、プロダクション用のコード出力は以下のコマンドを実行することで、dist/ フォルダに出力されます。

```
> yarn build
```

## 補足
Angular2 の構文が、一部 pug で（そのままだと）コンパイルエラーになるのでカンマで区切る、またはシングルクオートでくくるといった書き換えが必要です。
[Quated Attributes | pug](https://pugjs.org/language/attributes.html)

```
# カンマなし。error (click) が解釈できない
div(class='div-class' (click)='play()')

# カンマあり。ok (click) が解釈できる
div(class='div-class', (click)='play()')
```

## 蛇足
Angular2 は学習コストが高いとよく言われている気がしますが、Angular1が無秩序（？）に進化したのに比べて随分洗練されていて、コマンド一発でプロジェクトも作成でき、『サービスやコンポーネントなどの思想も含めて、目的に対して必要なことだけ学べばよい』仕様になっていて、『どちらにせよ学んだ方がいいこと』を学べば使えるように見えますので、触ってみたいけどなんか難しそう…と思ってる方は、Google Chrome のページ翻訳が超高性能になりましたので、分かりやすい本家のチュートリアルを日本語でお楽しみ頂くのもよいかと思います。
[TUTORIAL: TOUR OF HEROES](https://angular.io/docs/ts/latest/tutorial/)

## 蛇足２
開発には VisualStudioCode を使うと快適な気がします。

以上です。