Riot.jsでSPAを作る

# はじめに
この記事は[株式会社アイスタイルアドベントカレンダー](http://qiita.com/advent-calendar/2015/istyle)の5日目の記事です。

新規案件をLaravel5.1で開発しています。@kubotakです。
元デザイナー・コーダーなのでフロントエンドの方が得意な気がします。

今回は簡単な導入として事前コンパイルやbrowserifyなどはしません。
あくまでもルーティング方法のみの説明となります。

# Riot.jsについて

http://riotjs.com/ja/

> A React-like user interface micro-library

Reactを意識して作られた超軽量のUIライブラリ。
Riot（=反乱）は、ボイラープレート(=雛形、決まり文句)と、不要な複雑さにまみれた現在の潮流に「反旗」を翻すプロジェクト。

超軽量と云うだけあってGitHubリポジトリに以下のように書かれている

### Framework Size Comparison

| Framework              | Version    | Minified Size |
|------------------------|------------|---------------|
| Ember                  | 1.13.3     | 493.3kb       |
| Angular                | 1.4.2      | 145.5kb       |
| React                  | 0.14.1     | 132.6kb       |
| Web Components Polyfill| 0.7.5      | 117.1kb       |
| Polymer                | 1.0.6      | 101.2kb       |
| Riot                   | 2.3.11     | 18kb          |

他にもVirtualDOMを扱う[Mithril.js](http://mithril.js.org/)という軽量ライブラリもあるが、Riot.jsの良さはやはり見慣れたDOMの書き方だと思う。

そのへんはRiot.js公式の[React.jsとの比較](http://riotjs.com/ja/compare/)をみるとわかりやすい。

# カスタムタグ
ここでは割愛しますが、Riot.jsではReact.jsで言うJSXの機能を担うカスタムタグというものがあります。
今回は

* home.tag
* hello.tag
* not-found.tag

を作成して
`http://hoge.com/` -> `home.tag`
`http://hoge.com#hello` -> `hello.tag`
上記以外 -> `not-found.tag`
が読み込まれるようにルーティングしたいと思います。


# Route

ルーティングを定義していきます。
標準のルーターでも良いですが今回は[こちら](https://github.com/gabrielmoreira/riot-router)を使って行きます。

```
$ npm i --save riot riot-router
```

定義は以下

```js:app.js
// Compile all tags
riot.compile(function() {

    // Mount all Riot tags.
    riot.mount('*');

    // My app routes
    var
        Route = riot.router.Route,
        DefaultRoute = riot.router.DefaultRoute,
        NotFoundRoute = riot.router.NotFoundRoute,
        RedirectRoute = riot.router.RedirectRoute;

    riot.router.routes([
        new Route({tag: 'hello'}),
        new DefaultRoute({tag: 'home'}),
        new RedirectRoute({from: 'h', to: 'hello'}),
        new NotFoundRoute({tag: 'not-found'}),
    ]);

    // Start routing
    riot.router.start();
});
```

定義の詳細ですが、

## `new Route()`
基本はこれで行います。
`new Route({tag: 'hello'})`の場合カスタムタグの`<hello></hello>`が`http://hoge.com#hello`にアクセスされた場合に`<route></route>`にセットされます。

クエリパラメータを使う場合は以下
`new Route({path: 'hello/:userId' ,tag: 'hello'});`
`path`でルーティングを指定します。

`http://hoge.com#hello/1`
にアクセスされた場合は`hello`カスタムタグ内で`:userId`を以下のように取得できます。

```
<hello>
    { userId } = 1
    this.userId = 1
</hello>
```

## `new DefaultRoute`
ルートにアクセスされた場合に`<route></route>`にセットされます。

## `RedirectRoute`
リダイレクトを定義できます。
`{from: 'h', to: 'hello'}`とした場合は`http://hoge.com#h`にアクセスした場合`http://hoge.com#hello`に変換します。リダイレクトとは言いますが実際にhttp通信するわけではありません。

## `NotFoundRoute`
定義していないURLにアクセスした場合に読み込むカスタムタグを指定できます。

# HTML
HTMLは以下のようになります。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Riot Routing Test</title>
</head>
<body>
    <ul>
        <li><a href="/">HOME</a></li>
        <li><a href="#hello">HELLO</a></li>
        <li><a href="#404">NOT FOUND</a></li>
    </ul>
    
    <route></route>
    
    <!-- tags -->
    <script src="hello.tag" type="riot/tag"></script>
    <script src="home.tag" type="riot/tag"></script>
    <script src="not-found.tag" type="riot/tag"></script>
    
    <script src="node_modules/riot/riot+compiler.min.js"></script>
    <script src="node_modules/riot-router/lib/router.min.js"></script>
    
    <script src="app.js"></script>
</body>
</html>
```

# DEMO
http://plnkr.co/K6NOCzA3nK2W31rdDfbH

# 所感
ルーティングもシンプルで簡単にSPA(Single Page Application)が作成できました。
Riot.jsは学習コストがかなり低いので試しに使ってみては如何でしょう。

明日は@YuyaAboくんです。