新しい暴動のお時間です。 〜Riot.js v4(beta版) の変更点をピックアップ〜

# :warning: 注意事項 :warning:

本記事で触れている `Riot.js（以下、riot）` のバージョンは `4.0.0-beta2` です。
正式リリースの際は仕様が変わっている可能性がありますので、ご注意ください。

# `v4` が来る

riot の [公式リポジトリ](https://github.com/riot/riot/tree/dev) を見ていますが、メジャーアップデートである `v4` がリリースされるのも秒読みに入ってきたようです。今回は v2→v3 以上の、__破壊的変更が多く含まれる__ようですので、v3→v4 に乗り換える予定がある方は、今のうちからキャッチアップしておくと良いかと思います！

# 変更点のピックアップ

ではさっそく変更点を見ていきます。かなりガッツリと破壊的変更が入ります。
とりま、目次的に列挙します。[^1] 個人的にバグ？と思うものは :warning: を付けています。

1. カスタムタグファイルの拡張子の変更
2. インクルードの `type` 指定の変更
3. マウント先のタグの指定が `is` に変更になった
4. `mount` メソッドにワイルドカード、id指定が使えなくなった:warning:
5. `mount` メソッド単体ではエラーになる:warning:
6. カスタムタグの `script` に `export default {}` が追加
7. ライフサイクルメソッドの書き方が変更
8. カスタムタグの中の引数が `props, state` に変更
9. `riot.observable` の切り出し

ここからは一つ一つ見ていきましょう！

## 1. カスタムタグファイルの拡張子の変更

v3まで:　`.tag`
v4:　`.riot`

となりました。
シンタックスハイライトが効かない問題が発生すると思いますが、`Vue.js` のように拡張子に個性が出たのは私としては嬉しいです :smile: （~~それに、元々 `.tag` はシンタックスハイライト効きませんでしたので、それほど問題はないですしねw~~）

## 2. インクルードの `type` 指定の変更

v3まで:　`type="riot/tag"`
v4:　`type="riot"`

`/tag` の部分がなくなって、スッキリしましたね :thumbsup: 

## 3. マウント先のタグの指定が `is` に変更になった

これはコードを見てもらったほうが早いですね。簡単に言うと、以下の書き方が使えなくなりました。

```html:カスタムタグ

<body>
  <div data-is="app"></div>
  <div id="target"></div>
</body>
```

~~これはダメージ受ける方も多い気がしています…　`<app>`　という独自のタグを設置するより、困ったときの `<div>` を設置し、そこにマウントしている事例は結構耳にしていますので。~~

~~CSS のクラス設計的にも、div タグに `id, class` を振ってスタイリングしているでしょうし。~~


__※ 2019-03-26 追記__
@black-trooper さんに教えていただきまして確認しました。`data-is`→`is` になったようです。

```html:isによる指定
<body>
  <div is="app"></div>

  <script>
    riot
       .compile()
       .then(() => {
          // mountメソッドの引数の書き方も変更になった模様
          riot.mount("[is=app]", {/*...*/})
       })
       .catch((err) => {
          console.error(err)
       })
  </script>
</body>
```

こちら、[デモ](https://codesandbox.io/s/1oq589wlv4) も用意しましたので触ってみてください :hand_splayed: 

## 4. `mount` メソッドにワイルドカード、id指定が使えなくなった:warning:

以下の二通りの書き方が使えなくなってました。

```js:マウントメソッド
riot.mount('*', {/*...*/})
riot.mount('app', '#target', {/*...*/})
```

これは、ワンチャン不具合だったという事ないかなぁ。。。[^2]

## 5. `mount` メソッド単体ではエラーになる:warning:

これこそ不具合であってほしいです。一回 `compile` を挟まないといけないのは微妙…w

```js:マウントメソッド
// 以下はエラーとなる
riot.mount('app', {/*...*/})

// こちらは正しくマウントされる
riot
   .compile()
   .then(() => {
      riot.mount('app', {/*...*/})
   })
   .catch((err) => {
      console.error(err)
   })
``` 

## 6. カスタムタグの `script` に `export default {}` が追加

v4 から、カスタムタグの `script` が以下のようになります。

```html:カスタムタグ
<script>
   export default { // new!!
      // 引数については後述
      onBeforeMount(props, state) {
         console.log('I will be soon mounted :)')
         this.state = {
            select: props.params.foods
         }
      },
      onMounted() {
         console.log('I was mounted :)')
      }
   }
</script>
```

## 7. ライフサイクルメソッドの書き方が変更

全部書くのは冗長ですので、`before-mount, mount` イベントのみ書きます。

```js:ライフサイクルメソッド
// v3まで
this.on('before-mount', {/*...*/})
this.on('mount', () => {/*...*/})

// v4 ※引数については後述
onBeforeMount(props, state) {/*...*/)
onMounted(props, state){/*...*/}
```

こちらの方が、明示的にイベントハンドラとなって良いですね :thumbsup:

## 8. カスタムタグの中の引数が `props, state` に変更

v3まで:　`opts`
v4:　`props, state`

となりました。（~~物凄く `React` 感~~）
今のところ `state` の扱いがよくわからなく、`props` のまま使うか、カスタムタグ内の別の変数用意して保持するでも良い気はしていますが、そのためにメモリ使うのもあれなんで、私は以下のように props の値を state に放り込んでいます。

```js:stateの扱い
export default {
   onBeforeMount(props, state) {
      // stateを初期化し値をセット
　    this.state = {
         message: props.message
      }
      console.log('I will be soon mounted :)')
   }
}
```


## 9. `riot.observable` の切り出し

マウントされたカスタムタグ内で `console.log(riot)` を出力した結果を以下に添付します。

![スクリーンショット 2019-03-25 14.13.20.png](https://qiita-image-store.s3.amazonaws.com/0/48034/2715210d-d6fe-abac-8d45-49ead1037aac.png)

…確かに `observable` がいなくなってます。
この機能もちょいちょい使ってたので、ちょっと残念です…

`observable` を使いたい方は、別途 [riot-observable](https://www.npmjs.com/package/riot-observable) をimport, includeする必要があります。

[参考](https://codesandbox.io/s/9yk038r0kw)

# 終わりに

個人的には、かなり書き方が変わった印象ですね。噂通り、全体的に `React` に寄った感じがしました。

また、公式サイトもリニューアルされる（かもしれない）ので、そちらも楽しみです！さらに、[ロゴも変更になる](https://github.com/riot/logo/issues/3) ところですね！今のところいくつかアイディアが投げられていますが、全部 [@nibushibu](https://twitter.com/nibushibu) さん一人の案ですので、他の方のアイディアも見てみたいところ。

あとはどれくらいパフォーマンス改善された[^3]のかを、実際に書いてみないとわからないのと、その他サードパーティ製ライブラリとの親和性が懸念かなーってところです。それでは皆さん、v4 を期待して待ちましょう！

では(=ﾟωﾟ)ﾉ

参考デモURL
* [https://codesandbox.io/s/q8n4v2rqo6](https://codesandbox.io/s/q8n4v2rqo6)
* [https://codesandbox.io/s/l4150m6ko9](https://codesandbox.io/s/l4150m6ko9)
* [https://codesandbox.io/s/o452941pn6](https://codesandbox.io/s/o452941pn6)

[^1]: 私が観測したもののみですので、これ以外にもあると思います。
[^2]: [roadmap](https://github.com/riot/riot/issues/2515) でも議論には上がっていますが流されている感じがします。。。
[^3]: [Alpha.6のデモ](https://codesandbox.io/s/vq43rw5z70) 見る限り割と早くなった印象です。