ES6 を学べる tower-of-babel を作りました。 (workshopper の作り方)

さて、NodeSchool が開校された時に、ES6を学べるチュートリアル的なものがほしいと思い、tower-of-babelという名前のチュートリアルツールを作成しました。

github.com


このツールはnpm/node.jsを使って作っています。実際に動かすときはnpmがあれば動きます。
npmのインストールは他の記事を参考にしてください。npmが入っていれば、以下のようにすれば実行可能です。

$ npm install tower-of-babel -g
$ tower-of-babel

そうすると下記のようなダイアログが起動するのでエクササイズを選択して各種問題を解いてください。
全ての問題を解き終わった頃にはなんとなく ES6 の構文が使いたくなってくるはずです。

https://cloud.githubusercontent.com/assets/555645/6997242/a65df93c-dbef-11e4-9bf8-f39331c56d1f.png

なにか問題があれば気軽に tower-of-babel のリポジトリに連絡をください。

github.com

以下の話はworkshopperを作ってみたい方限定です。

workshopperの作り方

さて、NodeSchoolが如何に素晴らしいか、如何に初心者のNode.jsを押し上げるのに一役買っているかは前回の記事で軽く触れましたが、同じカリキュラムしか存在しないと受講生のみんなは飽きてきます。

今でもNodeSchoolには素晴らしいカリキュラムが数多く存在しますが、自分達から率先して新しいカリキュラムを作るのも良いと思います。

今回はそんな形で新しいカリキュラムを作るのにどうやって作ったらいいのか、 解説します。
今回のブログを読めば大体みんな作れるようになるかと思います。

workshopper / workshopper-exercise のインストール

適当なプロジェクト名のフォルダを作り、 npm init で package.json のひな形を作っておいてください。

$ npm init
$ npm i workshopper workshopper-exercise -S

workshopper の実体はあのファンシーなターミナルメニューを持つテストランナーです。
workshopper-exercise はテストランナーに対する validator、つまりアサーション機能の役割を果たしています。

最近では workshopperをさらに機能拡充した workshopper-adventure があります。これはworkshopper 新バージョンのβ版的な位置づけで色々便利な機能があります。大阪NodeSchoolのオーガナイザーである マーティンが作っています。

workshopper の定義を行う

プロジェクトフォルダの適当なファイルを作ってそのファイルを実行できるようにします。

tower-of-babelの場合は、 プロジェクトフォルダのルートに `tower-of-babel.js` を作ってそこに定義を書きました。

#!/usr/bin/env node

const workshopper = require('workshopper-adventure');
const path        = require('path');

function fpath (f) {
  return path.join(__dirname, f)
}

workshopper({
  name        : 'tower-of-babel',
  title       : 'Tower of Babel',
  subtitle    : 'Learn ES6 features using babel',
  appDir      : __dirname,
  menuItems   : [],
  languages   : ['ja'],
  exerciseDir : fpath('./exercises/')
})

こんな感じ。

エクササイズを作っていく

ここまで行くと後はエクササイズを作っていくまでです。

exercises フォルダを作成し、その中に menu.json を作りましょう。

[
    "BABEL SETUP",
    "CLASS",
    "CLASS EXTEND",
    "MODULES WITH NAME",
    "MODULES DEFAULT EXPORT",
    "BLOCK SCOPE",
    "COMPUTED PROPERTY",
    "ITERATOR FOR OF",
    "GENERATOR",
    "DESTRUCTURE",
    "ARROW FUNCTION",
    "REST AND SPREAD"
]

このmenu.jsonの配列の要素一つ一つがエクササイズになります。このエクササイズのフォルダを作成します。

フォルダを一個一個作成してもいいんですが、以下のコマンドを実行すると勝手にスケルトンが作られて便利です。

$ node_modules/workshopper/util/makews.js exercises/menu.json
exercises
├── arrow_function
│   ├── exercise.js
│   ├── problem.ko.md
│   ├── problem.md
│   └── solution
│       └── solution.js
├── babel-processor.js
├── babel_setup
│   ├── exercise.js
│   ├── problem.ko.md
│   ├── problem.md
│   └── solution
│       └── solution.js
├── block_scope
│   ├── exercise.js
│   ├── problem.ko.md
│   ├── problem.md
│   └── solution
│       └── solution.js
├── class
│   ├── exercise.js
│   ├── problem.ko.md
│   ├── problem.md
│   └── solution
│       └── solution.js
├── class_extend
│   ├── exercise.js
│   ├── problem.ko.md
│   ├── problem.md
│   └── solution
│       └── solution.js
├── computed_property
│   ├── exercise.js
│   ├── problem.ko.md
│   ├── problem.md
│   └── solution
│       └── solution.js
・・・

exercise.js にexerciseをrun, verifyした時の検証の方法を記述します。
problem.md に 問題文そのものを記述します。markdownで書けます。
solution/solution.js に回答のJavaScriptを記述します。

実際の例を上げるとこんな感じです。

block scopeの問題の例

exercise.js
problem.md
solution.js

exercise APIを覚える

tower-of-babelで利用しているexerciseは全て同じ作りをしていて、原理から説明すると、受講生が記述するファイルとsolution.jsをbabelでtranspileした後、child_processを使って実行し、標準出力の結果が同じかどうかをチェックします。

中の構造が同じかどうかまではチェックしておらず、同じ出力結果が出ること、期待しているキーワードを使っていることしかチェックしていません。

tower-of-babelで使っているのは以下のAPIです。

  • filecheck API (指定されたファイルが存在するかチェックするAPI)
  • execute API (child_processを使ってファイルを実行するAPI)
  • comparestdout API (標準出力結果をチェックするAPI)

使い方はこの辺を見てください。

tower-of-babel/exercise.js at master · yosuke-furukawa/tower-of-babel · GitHub

まとめ

tower-of-babelを作って、公開しました。ES6を学びたい皆様、ぜひぜひやってみてください。
あと、 5/23 (土) にもまた NodeSchool International Day でこれを学べるようにしようと思います!!

ちなみに、tako-blackさんが learnyoureact っていうreact 学習用のツールを作ってくれました。
こちらもNodeSchool International Day で出る予定です。