build を制するものはAngularを制する

# About Me

* Name: @Quramy
* Angular力: ドラゴンボールで言うと餃子くらい(そこら辺の幼稚園児よりは書けるけどナッパみたいなやつにはかてない)
* 趣味: 自作したVimのTypeScript用プラギンをメンテすること

<img width="100px" src="https://qiita-image-store.s3.amazonaws.com/0/8808/profile-images/1473681159" alt="" />

---

## TL;DR;

---

### 「ビルドタスクを書ける奴はPrjに1人いればいい」

---

### ...マジで言ってんの？

---

### 自分で書けるようになった方が良い

---

## Today's theme: Module bundler

---

### Weapon of choice?

#### **webpack**
v2.xからはTree Shaking(import した対象のみbundleする機構)がデフォルトで利用可能に。angular-cli等、公式でも採用されている。
「何でも出来てしまう」ツールなので、使い方を間違うとwebpackと心中する羽目になる.

#### Rollup
ES2015に最適化されたTree Shakingは魅力。Webpack2よりもbundleのサイズを削れるとの報告も.

#### SystemJS/JSPM
Angular.ioのtutorialに記載されているものの、使う必然性がない。唯一の利点はPlunkerで動作させることが可能な点か。

#### Browserify
特に書くことが思い浮かばない。

---

## でもwebpackと心中したくない

---

### e.g. CSS pre-processor

こんなコード、書いちゃってない？

```ts
@Component({
  template: `<h1>hello</h1>`,
  styles: [require('raw-loader!sass-loader!./my-app.component.scss')],
})
export class MyApp {}
```

---

### Locking into module bundler

CSSとかrequireもimportもできないから。
それwebpackと心中する覚悟あるって意味だけど、大丈夫？

話は逸れるが、CSS Modules使ってる奴はそれぐらいの覚悟あるってことなんだろうな？

---

### angular2-template-loader

```js
styleUrls: ['./my-app.component.scss']
```

<span class="fa fa-arrow-down"></span>


```js
styles: [require('./my-app.component.scss')],
```

と変換されれば、ソースコードからwebpack依存を引っぺがせる


```ts
@Component({
  template: `<h1>hello</h1>`,
  styleUrls: ['./my-app.component.scss']
})
export class MyApp {}
```

これをやってるのがangular2-template-loader.

---

### How to write configure file

```js:webpack.config.js
modules: {
  loaders: [
    {
      test: "\.component\.ts$", exclude: /node_modules/,
      loaders: [
        "awesome-typescript-loader",
        "angular2-template-loader", /* これ */
      ]
    },
    {
      // Scssの場合
      test: "\.component\.scss$",
      loaders: [ "raw-loader", "sass-loader" ]
    },
    {
      // Post CSSの場合
      test: "\.component\.css$",
      loaders: [ "to-string-loader", "css-loader", "postcss-loader" ]
    },
  ]
}
```

---

### Remarks

angular2-template-loaderは只の文字列置換なので注意。

もしservice中に`templateUrl`っていうキーがあると`template: require()`に変換されるぞ！

```ts:input
myMethod() {
  const hoge = {templateUrl: "foo"};
  return hoge;
}
```

```ts:output
myMethod() {
  const hoge = {template: require("foo")};
  return hoge;
}
```

---

### e.g. Routing

```typescript
const routes: Routes = [
  {
    path: "sub",
    loadChildren: "./submodule#SubModule"
    // loadChildren: () => new Promise((resolve) => {
    //   require.ensure([], (require) => {
    //     resolve(require("./submodule")["SubModule"];
    //   });
    // })
  }
];
```

```js:webpack.config.js
modules: {
  loaders: [
    {
      test: "\.routing\.ts$", exclude: /node_modules/
      loaders: [
        "awesome-typescript-loader",
        "es6-promise-loader",
        "angular2-load-children-loader",
      ]
    }
  ]
}
```

---

## build筋(別名ウェブパッ筋)を身につける為には 💪

1. 筋トレしよう!
1. 良いbuildは良いseedに

---

## 筋トレしよう！

* `npm init` から始めて、自分で1からwebpack.config.jsを書いてみる
* 最初は写経でも良い
* GitHub Pages等にbundleをdeployするところまでタスクを作成してみる
* ディレクトリ構成をどのようにすべきか、等 module bundler以外の知識も色々得られるはず
* build筋はAngular以外のプロジェクトでも活きる

---

## 良いbuildは良いseedに

基礎体力がある人は、良く出来たseedを覗いてノウハウを盗みまくる。
「なるほど、こんなloaderがあるのか」といった知見が得られるはず。

<ul>
  <li><a href="https://github.com/angular/angular-cli" target="_blank">
    <span class="fa fa-github"></span>
    angular/angular-cli
  </a></li>
  <li><a href="https://github.com/AngularClass/angular2-seed" target="_blank">
    <span class="fa fa-github"></span>
    AngularClass/angular2-seed
  </a></li>
  <li><a href="https://github.com/AngularClass/angular2-webpack-starter" target="_blank">
    <span class="fa fa-github"></span>
    AngularClass/angular2-webpack-starter
  </a></li>
</ul>

---

# Thank you!