Riot 2.0を試してみる（Compiler編

https://muut.com/riotjs/compiler.html

[前回](http://qiita.com/kazusa-qooq/items/66047d74596ddb494df9)、Riotのホームページの紹介文を読み、Riotがどのようなものかなんとなくわかってきました。今回は実際にRiotを使ってみましょう。
ただRiotさんの簡単なGet-Startedが見つかりませんでした・・・
というわけで地道に行きます。まずはコンパイル編です。
次の２通りの方法があります

1. ブラウザ側でコンパイル
2. サーバ側で事前コンパイル

理解しやすくするためにカスタムタグと変換後のJavaScriptを最初に載せておきます。

コンパイル前

``` src.tag
<my-tag>
  <h3>My layout</h3>

  <script>
    this.hello = 'world'
  </script>
</my-tag>
```

コンパイル後

``` src.js
riot.tag('my-tag', '<h3>My layout</h3>',
 function(opts) {
  this.hello = 'world';
});
```

#Compiler
`<custom-tag>`からJavaScriptへ
##In-browser compilation
ブラウザの実行前にカスタムタグはJavaScriptにコンパイルされる必要があります。スクリプトタグに`type="riot/tag"`を設定することで、これが可能です。

``` example.
<!-- mount point -->
<my-tag></my-tag>

<!-- inlined tag definition -->
<script type="riot/tag">
  <my-tag>
    <h3>Tag layout</h3>
    <inner-tag />
  </my-tag>
</script>

<!-- <inner-tag/> is specified on external file -->
<script src="path/to/javascript/with-tags.js" type="riot/tag"></script>

<!-- include riot.js and the compiler -->
<script src="//cdn.jsdelivr.net/g/riot@2.0(riot.min.js+compiler.min.js)"></script>


<!-- mount normally -->
<script>
riot.mount('*')
</script>
```
type="riot/tag"のスクリプトタグは、通常のJavaScriptと組み合わせたタグの定義を複数含めることができます。
Riotは自動的に、`riot.mount()`によるタグのレンダリング前に、カスタムタグをJavaScriptに変換します。
例：https://jsfiddle.net/kzqooq/4eomjsma/

###Access tag instances
カスタムタグにアクセスする必要があるなら、`riot.mount()`を次のようにします。
例：https://jsfiddle.net/kzqooq/4eomjsma/1/

``` example.
<script>
riot.compile(function() {
  // here tags are compiled and riot.mount works synchronously
  var tags = riot.mount('*')
  var mytag = tags[0]
  alert(mytag.root.nodeName)
  console.log(tags)
})
</script>
```
###Compiler performance
コンパイルは高速です。[タイマータグ](https://github.com/muut/riotjs/blob/master/test/tag/timer.tag)を３０回コンパイルしても２msしかかかりません。よほどクレイジーな呼び出しをしているページでも35msでしょう。
さらにコンパイラは3.2kbしかありません。gzipなら1.7kbです。よってパフォーマンスは問題になりません。
さらにはIE8でも動きます。
詳細は[API](https://muut.com/riotjs/api/#compiler)を見てください。
デモ：[In-browser compiled](http://muut.github.io/riotjs/demo/)

##Pre-compilation
しかし、事前コンパイルにも利点はあります。

* CoffeeScriptなど好きな[プリプロセッサー](https://muut.com/riotjs/compiler.html#pre-processors)が使えます
* パフォーマンスがブラウザ側でやるより多少良いです

事前コンパイルにはriotをnpmでインストールする必要があります。

```
~/workspace/riot (master) $ npm install -g riot
npm WARN optional dep failed, continuing fsevents@0.3.5
/home/ubuntu/.nvm/v0.10.33/bin/riot -> /home/ubuntu/.nvm/v0.10.33/lib/node_modules/riot/lib/cli.js
riot@2.0.14 /home/ubuntu/.nvm/v0.10.33/lib/node_modules/riot
├── minimist@1.1.1
├── shelljs@0.4.0
├── simple-dom@0.2.2
├── simple-html-tokenizer@0.1.1
└── chokidar@1.0.1 (arrify@1.0.0, is-glob@1.1.3, glob-parent@1.2.0, async-each@0.1.6, is-binary-path@1.0.0, readdirp@1.3.0, anymatch@1.2.1)
```

事前コンパイルした場合、以下のような記述になります。事前コンパイルによりカスタムタグからJavaScriptに変換したファイルを読み込んでいます。

``` example.
<!-- mount point -->
<my-tag></my-tag>

<!-- include riot.js only -->
<script src="//cdn.jsdelivr.net/riot/2.0/riot.min.js"></script>

<!-- include pre-compiled tags (normal javascript) -->
<script src="path/to/javascript/with-tags.js"></script>

<!-- mount the same way -->
<script>
riot.mount('*')
</script>
```

コンパイルの仕方はいくつかあります。
なお、１つのソースファイルでカスタムタグを複数定義できます。

``` ファイルを指定.
# compile a file to current folder
$ riot some.tag 
some.tag -> some.js
```

``` 出力フォルダを指定.
# compile file to target folder
$ riot some.tag some_folder
some.tag -> some_folder/some.js
```

``` 出力ファイルを指定.
# compile file to target path
$ riot some.tag some_folder/some.js
some.tag -> some_folder/some.js
```

``` フォルダ内のカスタムタグを全てコンパイル.
# compile all files from source folder to target folder
$ riot src dest
src/some.tag -> dest/some.js
```

```　フォルダ内のカスタムタグを全て１JavaScriptにまとめる.
# compile all files from source folder to a single concatenated file
$ riot src all-my-tags.js
src/some.1.tag -> all-my-tags.js
src/some.tag -> all-my-tags.js
```

###Watch mode
以下のコマンドで自動コンパイルできます。
１ファイルに変更があると全ファイルが再コンパイルされます。

``` 監視.
$ riot -w src dist
src/some.1.tag -> dist/some.1.js
src/some.tag -> dist/some.js
Watching src/**/*.tag
src/some.1.tag -> dist/some.1.js
src/some.tag -> dist/some.js
```

###Custom extension
ソースファイルのデフォルトの拡張子はtagですが、--extオプションで変更可能です。

``` ソース拡張子変更.
$ riot --ext html src dist             
src/some.html -> dist/some.js
```

###Node Module
Node上でコンパイル可能です。

``` ソース.
var riot = require('riot')
var source_string="<h1>aaa</h1>"
var js = riot.compile(source_string)
console.log(js)
```

``` 実行結果
$ node src.js
riot.tag('h1', 'aaa', function(opts) {
});
```

各種プラグインも用意されています。

* [Gulp](https://github.com/e-jigsaw/gulp-riot)
* [Grunt](https://github.com/ariesjia/grunt-riot)
* [Browserify](https://github.com/jhthorsen/riotify)

###Pre-processors
--type, --templateオプションによりCoffeScriptやJadeなどを使ってカスタムタグが定義できます。

``` CoffeeScript+Jade.
sample
  p test { value }
  script(type='text/coffeescript').
    @value = 'sample'
```

``` コンパイル.
$ riot --type cs --template jade src.tag
src.tag -> src.js
```

``` コンパイル後.
riot.tag('sample', '<p>test { value }</p>', 
  function(opts) {this.value = 'sample';

});
```

使用できるプリプロセッサを以下になります。なおそれぞれnpmでのインストールが必要です。また自作も可能です。
JavaScript:

* CoffeeScript
* EcmaScript 6
* TypeScript
* LiveScript

HTML:

* Jade


#まとめ
HTMLとJavaScriptでちゃっちゃか作るならブラウザコンパイル、ファイルの分割とかJadeとか使うなら事前コンパイルといったところでしょうか。[次回](http://qiita.com/kazusa-qooq/items/674596601636b8e20023)はカスタムタグの作り方を見ていきたいと思います。