チームをReady for Riotにするワークショップ

この記事は[Riot.js Advent Calendar 2016](http://qiita.com/advent-calendar/2016/riotjs)の24日目の記事です。

## 前置き

### ご注意

ある程度Riotが分かっている人が、JavaScript初心者のチームにRiot的な考え方に親しんでもらうワークショップについて書いた記事です。

Riotについての説明はほぼ皆無ですので、ご注意を。

### Riotなら誰でも使いこなせると思った

[Riot.js](http://riotjs.com/)、良いですよね。JavaScript初心者集団でも、現代的なコンポーネント指向でサクサク作れるようになんて、夢のようじゃないの！
……そんな風に思って、Riotの基礎の勉強会を開催。
「大まかにはこんな感じだから、後は公式サイトを見てね」で勉強会を終えて、さっそく実戦投入してみました。

結果！
うん、まあ、導入の勉強会はもっと丁寧にやるべきだよね……。ごめんなさい。

### チームの状況・理解の状況

当時のチーム(デザイナ＋PHPプログラマ)のJavaScriptレベルは、

* 「こういうのを作るには、jQueryのどのライブラリ使えばいいのかな？」

くらいが平均的な理解度。それでも特に業務に支障が出ない現場です。

とはいえ、そのままではあまりよろしくないので、Riotあたりでモダンな世界に少しずつ足を踏み入れていこうよ、という感じで新規プロジェクトに投入。

全体の構成やJavaScriptの実装などの基本的な部分は全部私が作って、見た目に関する細部の実装をチームメンバーにお願いしましたが、主にCSSのコーディングで多大な苦労をかけることに……。

他のプロジェクトでも小さく導入してみたのですが、カスタムタグが複数になると、構造や関係の理解がなかなか得られません。

どうも「コンポーネント単位で考える」というところに根本的な課題がありそうです。

そこで、後日改めて以下のような内容のワークショップを開催しました。

## チームをReady for Riotにするワークショップ 'Riot Button Challenge'

教材はこちら
[hidk/RiotButtonChallenge](https://github.com/hidk/RiotButtonChallenge)

### ワークショップが対象とする参加者像

* jQueryライブラリが使える程度のJavaScript力はある
* ES6系の実装経験ほぼゼロ。噂くらいは知っている
* Riotの実装経験ほぼゼロ。なんとなくどういうものかは知っている
* SASS等のaltCSS経験ほぼゼロ。話くらいは知っているが、使い所がわからない

### ワークショップの主催者像

* Riotの公式サイトに書いてある内容は一通り理解している
* SASSやStylus等のaltCSSをある程度知っている
* npmを活用した開発をできなくもない

### Riot Button Challengeの内容

#### 1. ボタンのカスタムタグを作ろう

* 予め用意してある`my-botton.tag`を改造しよう
* ボタン名をオプションで自由に指定できるようにしよう
* ボタンの見た目を2種類用意して、マウント時のオプションで指定できるようにしよう
* ボタンクリックしたら、ボタン名をalert()で表示しよう

#### 2. ボタンを２つ並べるカスタムタグを作ろう

* 予め用意してある`my-button-group`を改造しよう
* 作成したボタン`my-botton`を2つ並べてマウントするカスタムタグを作ろう
* 親(index.html)が子(my-button-group)をマウントし、子が孫(my-button)をマウントする構造にしよう
* 2つのボタンはそれぞれ違った見た目になるようマウントしよう

#### 3. オプションを使いこなそう

* `my-button-group`を改造しよう
* 孫(my-button)のクリックアクションを親(index.html)の気分次第で自由に変えられるようにしよう
* ボタンのカスタムタグを改造せずに機能の種類を増やせるようにする

### ワークショップの狙い

本当の基礎の基礎を「感覚として身につける」ことをゴールにしています。

具体的には、

* カスタムタグのマウント
* カスタムタグのオプション指定
* 複数のカスタムタグのマウント
* 親子関係のあるカスタムタグのマウント
* クリックイベントの作り方
* 変更に強いカスタムタグのヒントを少しだけ
* `each`によるループを軽く

といった内容。
既にRiotが分かる人だと、わざわざ説明しなくても公式ドキュメントを読めばわかりそう……とか思ってしまうかもしれません。しかし、jQueryのいつまでも変わらない吸引力を侮ってはいけません。jQueryに縛られた魂を開放するのは、理屈でどうこうなるものではないのです。

なお、このワークショップでやらないこと（次回以降に回す内容）は以下の通り。

* タグ間の協調動作
* Observerble
* データと処理の流れの制御
* ルーティング
* Mixin

### ワークショップの進め方

#### 教材の配布

ワークショップで使うファイル群は事前に配布しておきます。

[hidk/RiotButtonChallenge](https://github.com/hidk/RiotButtonChallenge)

ワークショップ実施時は、タグをマウントするindex.htmlと2つのタグファイル、それにRiot.js本体の最小構成にしていましたが、このままではデバグがとてもやり辛いので、`npm`をなんとなくでも使えるチームなら、サーバと自動コンパイルのスクリプトを用意しても良いでしょう。

この先の解説は、教材をお手元に置いた上でお読みいただければ幸い。

#### 進め方

解説を交えながら、上から順に一緒に実装していきます。
一通りの解説が終わったら、あとで自力で同じものを実装してもらう形でも良いでしょう。
所要時間は1時間程度。

### セクションごとの狙い

ワークショップは3つのセクションに分かれています。セクションごとの小さな目標を順にクリアしていって、理解を深めていく構造です。

それでは、ワークショップの主催者向けに、各セクションの狙いを簡単に説明していきましょう。

#### 1. 単体のカスタムタグに親しむ　「ボタンのカスタムタグを作ろう」

HTMLとjQueryレベルのJavaScriptで簡単にできてしまうということをわかってもらうセクションです。解説ポイントを箇条書していきます。

* カスタムタグという概念
    * カスタムタグ内に書いた自分だけのタグに見た目と機能を実装できる
    * カスタムタグは、ほぼHTMLと同じような構成
        * HTMLのbodyタグ相当部分
        * styleタグ相当部分
        * scriptタグ相当部分
            * scriptタグを省略する「オープン構文」は一切取り上げない
* マウントの方法
    * HTMLでRiotの本体を呼ぶ
    * HTMLでカスタムタグを記述
    * `riot.mount`を実行
* カスタムタグへのオプションの与え方
    * `riot.mount`で渡す方法
    * カスタムタグの属性として書く方法
* 複数のカスタムタグのマウント
    * カスタムタグ外においても属性でオプションを指定すれば、難しげな書き方のマウントをしなくても大丈夫
        * 公式サイトで軽く勉強した人にとっては、これが意外と盲点
        * 軽くRiotを使う程度だと属性としてオプションを書く方法は初心者に親しみやすい
            * 「型」の問題があることは後日の説明で良いかと
* カスタムタグ内では`opts.*`で、与えられたオプションの内容を取り出せる
    * カスタムタグ内では`{}`の中がJavaScriptとして解釈される
        * `{}`のことはこの後もしつこく伝える

#### 2. 入れ子のカスタムタグに親しむ　「ボタンを２つ並べるカスタムタグを作ろう」

ここでは入れ子のタグと、DOM操作について学びます。

入れ子のカスタムタグのオプション指定は、意外と難関です。「カスタムタグは`mount()`でオプションを指定してマウントするもの」という理解が一度できてしまうと、`mount()`しないでマウントするときに途方に暮れやすいです。

また、DOM指定しないDOM操作も、話としては「ふんふん」という感じで理解されやすいのですが、実践となると話は別です。やっちゃいます、直接的なDOM操作。jQueryの重力、恐るべしです。

以下、このセクションの細かなポイントです。

* カスタムタグ内でのカスタムタグのマウントは`mount()`不要
* カスタムタグを組み合わせたものを、こうやって一つカスタムタグとして使える
* プリミティブな値だけでなく、オブジェクトをオプションにできる
    * プリミティブとかオブジェクトとかの言葉は使わないほうが無難
    * 「`function`すらオプションで渡せるよ」くらいの方が伝わりやすい
* ある要素にclassを当てて見た目を返るのに、DOM指定は不要
    * DOM操作は命令的・手続き的に行わず、定義・宣言で済ませる
    * 状態・定義を変えれば、自動的に見た目や挙動が変わるという便利さを強調
* Scoped CSSの概念
    * ざっくりCSSを書いてもカスタムタグ内に封じ込めることができる
    * 複雑なセレクタは不要になる
    * だから、構造の変更が気軽にできるようになる
    * グローバルなCSSで外からスタイルを当てるとこういった利点を損なうので注意
        * 共通のCSSはaltCSSを使って、importする方が扱いやすい（後でまた触れます）

#### 3. 入れ子のカスタムタグにさらに親しむ　「オプションを使いこなそう」

ここでは、親／子／孫の関係を作り、親のマウント時に孫までオプションを伝えることを中心に学びます。
また、カスタムタグに汎用性を持たせる方法論についても軽く紹介します。

例によって、このセクションのポイントです。

* オブジェクト型のオプションを用意して、`mount()`時に与えるのがよくある実装
* 子のタグ以下には、親から貰ったオプションをうまいこと伝えていく
* `opts`には、「自分の直接の親」が指定したオプションが入る
    * 親から子がもらった`opts`をバケツリレーで孫に渡せる
* Riotの`each`は便利
    * 現段階では、便利なことが伝わればOK
    * 細かいところは実戦投入時に手取り足取り教えるべき。ハマりどころ多し

## 最後に

このワークショップは、jQuery的な考え方から脱することに重きを置いています。現場で楽しくRiotを使いこなしてもらうためには、まだまだ足りない内容。

でも、きっとやれそうな予感は持ってもらえると思います。
チーム全体で"Ready for Riot"になったら、一緒にその先へ進んでいきましょう。