えんじにあ ときどき くらいまー

個人的な技術メモとかボルダリングのこととかなんか色々書けたらいいなぁ

Riot.js v2 => v3 の変更点まとめ

はじめに

Riot.jsを使用したSPAサイトの作り方シリーズを書いてる途中でRiot.jsのメジャーバージョンが2から3にあがりました。

なので、今回は2から3の変更点をまとめたいと思います。
(と言っても英語で書かれてるガイドをなんとなくで日本語訳しただけですが)

ついでに他の言語でも使用される英単語の簡単な説明もちょいちょい挟んでおきます。

訳は結構適当で、実際のガイドとはタイトルとか違ったりしてますので、
なんとなくで読んでください。

目次

Breaking changes

破壊的変更ですね。
新バージョンでは使用できなくなった機能のことです。

Deprecate

使用が推奨されていない機能のことです。
基本的に代用できるプログラムが用意されています。

riot-tag

riot-tag属性はDeprecateされました。代わりにdata-is属性を使用するようにしてください。

<!-- not supported -->
<div riot-tag="my-tag"></div>

<!-- good -->
<div data-is="my-tag"></div>

また、data-isはネストされたタグでも使用でき、動的に値を与えることも可能です。

<my-tag>
  <div data-is={ subComponent }></div>

  <script>
    this.subComponent = 'child-tag'
  </script>
</my-tag>

name, id

nameid属性はDOM参照をキャッシュするために使用されなくなります。
代わりにref属性を使用します。

<my-tag>
  <p ref="paragraph">Hello</p>

  <script>
    console.log(this.refs.paragraph) // => p node
  </script>
</my-tag>

オブジェクトループ

オブジェクトループでは、key, value in objectという構文でしたが、
value, key in objectという構文に切り替えました。

v2では配列をループする場合は、value, keyで値が入っていたのに対し、
オブジェクトをループする場合はkey, valueで値が入っていたので、どっちかに合わせましょうよっていう話があって入った変更ですね。

<my-tag>
  <ul>
    <li each={ key, value in obj }>
      keyは{key}。valueは{value}。
    </li>
  </ul>

  this.obj = { key1: 'value1', key2: 'value2', key3: 'value3' }
</my-tag>

<!-- v2で実行すると -->
keyはkey1。valueはvalue1。
keyはkey2。valueはvalue2。
keyはkey3。valueはvalue3。

<!-- v3で実行すると -->
keyはvalue1。valueはkey1。
keyはvalue2。valueはkey2。
keyはvalue3。valueはkey3。

ちなみに配列の場合

<my-tag>
  <ul>
    <li each={ value, i in array }>
      valueは{value}。iは{i}。
    </li>
  </ul>

  this.array = [ 'value1', 'value2', 'value3' ]
</my-tag>

<!-- v2, v3ともに -->
valueはvalue1。iは0。
valueはvalue2。iは1。
valueはvalue3。iは2。

Remove

削除。機能が無くなっちゃうってことです。
使ってたらError出るので要注意。

riot.route

riot.routeはRiot coreから削除されたため、ニーズにあったルーティングライブラリを使用することができるようになりました。
Riotやスタンドアロンモジュールとして利用できるriot-routeのメンテナンスは続けられます。

マウント前のupdate, updatedイベントのトリガー

以前はマウントイベントが発生する前でもupdate, updatedを起動していました。
before-mount, mountを使用して、タグを適切にマウントするとupdate, updatedイベントは結果的なアップデート呼び出しでのみ起動されます。

すみません。これちょっとこれ訳し方がよくわからないんですが、
要するに、今までmount前にudpate, updatedイベント起動してたけど、
これからはbefore-mountがそこやるんでよろしく。

ってことです。

自動preventDefault

任意のタグイベントでevent.preventDefault()を自動的に呼び出していましたが、この動作が間違っていると思ったので削除しました。

<my-tag>
  <form obsubmit={ ajaxSubmit }>
    <input>
  </form>

  <script>
    ajaxSubmit(event) {
      // v2では不要だが、v3では必要。
      event.preventDefault()
    }
  </script>
</my-tag>

カスタム子タグによって生成されたイベントに関する親タグの更新がされない

v2ではループ内のカスタム子タグによって生成されたイベントが親タグにも更新をトリガーしていました。
v3ではループされたカスタム子タグから親を更新する必要がある場合は、明示的に行う必要があります。

riot.observableでスペースを置いたイベントのサポート

スペースを置いたイベントのサポートを削除することで、riot.observableがv2よりも 6倍高速 になりました。

var el = riot.observable()

// v2での書き方(サポート終了)
el.on('start stop', function() { /* */ })
el.trigger('start stop')

// v3での書き方
function cb() {}
el
  .on('start', cb)
  .on('stop', cb)

el
  .trigger('start')
  .trigger('stop')

scoped属性

v3では、すべてのCSSはデフォルトでスコープされるため(Scoped cssがデフォルトになる)、<style>ノードではscoped属性は必要ありません。

<!-- v2での書き方 -->
<my-tag>
  <h1>Hello Riot<h1>
  <style scoped>
    :scope h1 {
      color: red;
    }
  </style>
<my-tag>

<!-- v3での書き方 -->
<my-tag>
  <h1>Hello Riot<h1>
  <style>
    :scope h1 {
      color: red;
    }
  </style>
<my-tag>

babel v5.8

ES6パーサーは最新のbabeのバージョンを使用します(babel v6以降を使用するため、旧バージョンのv5.8が使用できなくなりました)。

旧バージョンのbabelを使用するように、ES6パーサーを手動で設定することはできます。

※Riot.jsとしては、babelの代わりにbubléをサポートしています。

bublé

bubléはbabelと違い、ES5の仕様に準拠したコードにトランスパイルするのではなく、指定されたブラウザバージョンで動くコードへのトランスパイルを行います。
(babelはES2015からES5へのトランスパイルを行う。)

また、bubléはbabelに比べると高速でトランスパイルを行いますが、サポートしていない仕様が多々あるので使用する際は注意が必要です。
(ブラウザバージョンを指定してトランスパイルできるというのは凄く魅力的なんですが、サポートされていない仕様が自分にとっては結構クリティカルな部分なので、自分は使用しないかな。。)

テンプレートエラーの飲み込み

v2では、タグテンプレートのエラーを捕まえるために手動で設定しなければなりませんでした(設定しない限りエラー検知ができなかった)。
v3では、consoleAPIが利用可能なときはいつでも、すべてのテンプレートエラーがconsole.errorを使用して出力されます。

まとめ

  • v2からv3にあげる際は気を付けましょう。
  • 簡易サイト作るならbabelよりbubléの方が良い気がする。
    • その程度のサイトならES5で十分な可能性大なので、そもそもトランスパイラ要らない気がしますが。。
  • 英文訳すのツラい。。(自分でなんとなく読む分にはいいけど)