component 1.0.0のビルドコマンドを試してみた

ちょっと前になりますが4/1に[component](https://github.com/component/component)の1.0.0-rc1がリリースされました。

今はrc5みたいです、久しぶりにcomponentを触ってみて、ビルドのコマンドが以前より便利になっているようなのでまとめてみます。

サンプルのソースは以下にあります:

https://bitbucket.org/p_baleine/component-1.0.0-build-sample

## component buildの構成

npmモジュールの名前がややこしいのですが、以下のような依存関係があります。

```
component
  -> component-build
    -> builder2.js
```

`component build`は実際には[component/bin/component-build](https://github.com/component/component/blob/master/bin/component-build)を実行しますが、このスクリプトが直接依存しているのが[component-build](https://github.com/component/build.js)、その先に[builder2.js](https://github.com/component/builder2.js)がいます。間に`component-build`を挟んでいるのは、個々のプロジェクトにカスタマイズされたビルドをしたい場合はこれをフォークして好きなように弄ってくれという意味みたいです。

で、[component-build](https://github.com/component/build.js)に記載がある通り、特にカスタマイズせずとも`component build`で以下の機能がサポートされています:

* Scripts
  * ES6モジュールサポート
  * 文法エラーチェック
  * JSONファイルとJSONの文法エラーチェック
  * テンプレート
  * デフォルトでbundleの自動require
  * オプションでUMD wrap
  * bundleのentry pointを自動で解決

* Syles
  * 自動でCSSのベンダプレフィックス付与
  * 任意のプレフィックスでCSSのurlを書き換え

* Files
  * ファイルのコピーまたはsymlinkを選択

この内面白そうで試せたものについて記載します。

## es6-moduleのサポート

jsファイルをes6-moduleの文法で記述すると、es6-moduleをサポートしていないブラウザでも動くようにコンパイルしてくれます(lib/sample/index.js):

```js
import data from "./data";
import templateHtml from "./template";
import _ from "underscore";

var template = _.template(templateHtml);

export default = function render(el) {
  if (typeof el !== "string") { throw new TypeError; }
  document.querySelector(el).innerHTML = _(data).map(function(datum) {
    return template(datum);
  }).join('');
};
```

`component.json`に特別な指定はいらないようです。

## JSONファイル

以前はsegmentio の[プラグイン](https://github.com/segmentio/component-json)で実現できた`json`ファイルのrequireですが、組み込みになったようです。`component.json`に`json`という名前のプロパティで記載するとrequireできます。

```json
  "json": [
    "data.json"
  ]
```

## テンプレート

以前はテンプレート用のHTMLを作成してこれに対し`component convert`を実行してJSファイルを生成して、これを利用する必要がありましたが、今はビルドコマンドが組み込みで変換処理をもってくれています。`component.json`の`templates`に記載してrequireするとhtmlに記載した内容が文字列として得られます。

```json
  "templates": [
    "template.html"
  ]
```

## CSSのベンダプレフィックスの書き換え

これ便利ですね、何も考えずにCSSファイルにベンダプレフィックスを必要とするスタイルを記述すると、勝手にプレフィックスつけてくれました(lib/sample/sample.css)。

```css
/* ... */

#list {
  transform: rotate(-10deg);
}

/* ... */
```

ビルドされたCSS:

```
/* ... */

#list {
  -webkit-transform: rotate(-10deg);
  -ms-transform: rotate(-10deg);
  transform: rotate(-10deg);
}

/* ... */
```

## デフォルトでbundleの自動require

なに言っているんだかわかりにくいですが、例えばサンプルのアプリはローカルコンポーネント(`lib/sample`)を含むそれ自身が`component-1.0.0-build-sample`という名前のコンポーネントとして構成されています。で、以前はトップのhtmlの方で以下のように明示的に`component-1.0.0-build-sample`をrequireするようなコードを記述してアプリを起動していました

```html
<body>
  <!-- ... -->
  <script src="build/build.js" type="text/javascript"></script>
  <script>
    ;(function() {
      require('component-1.0.0-build-sample')
    }());
  </script>
</body>
```

でも最新の`component build`では生成されたbuild.jsの一番下のほうで`require("component-1.0.0-build-sample")`してくれているので、上記HTMLでいうところの2つ目の`script`タグがまるごといらなくなります。

## watch

ビルド時に`--watch`オプションをつけるとファイルの変更を監視して勝手にビルドしてくれます:

```bash
$ component build --watch
```

…これいつからあったんだろうなぁ、前はgruntのComponent向けプラグインとかで実現してたけど、component自身がサポートしてくれたみたいです。

# 終わりに

ちゃんと追っかけていなかったのでいつからこういう体制になったのかわからないんですが、最近は明確に[jonathanong](https://github.com/jonathanong)がメンテナになったみたいで、1.0-rc1のリリースも彼の[ツイート](https://twitter.com/jongleberry/status/451179293314252800)で知りました。

個人的に、このビルドコマンド周りの改善とかは、componentとしての理想もあるけれど、より便利な方に向かっているように思えました。

新(?)機能を全部試せていないので、他のもそのうち見てみます。