koaをCoffeeScriptで書く

tl;dr

  • koaは、JavaScript(ES6)のgeneratorを活用したnode.js向けのwebフレームワークです
  • CoffeeScriptの開発版で、最近generatorの構文がサポートされました
  • 早速、試しにCoffeeScriptでkoaを使ってみたらちゃんと動きました

Generatorとは?

JavaScriptの機能の一つです。
JavaScriptでは非同期的な処理の結果はコールバック関数で受け取るのが通例です。
しかし、例えばネットワーク通信系の処理などでは、コールバックが多くなりすぎてコードがとても複雑になってしまう問題がありました。
Generatorは、このコールバック地獄を解決できると期待されている機能です。

以下に、node.jsによるコールバック関数を使った非同期処理を記します:

var fs = require('fs');

// カレント ディレクトリーのファイル一覧を取得する
fs.readdir('.', function(err, files) {
    // 先頭のファイルの中身を読み取る
    fs.readFile(files[0], 'utf-8', function(err, data) {
        // 読み取った結果を出力する
        console.log(data);
    });
});

みづらいですね。
しかしGeneratorを使うと:

var co = require('co');
var fs = require('fs');

co(function *() {
  var files = yield co.wrap(fs.readdir)('.');
  var data = yield co.wrap(fs.readFile)(files[0], 'utf-8');
  console.log(data);
});

シンプル!
構文的には、function*yieldキーワードが新しい要素です。

詳しくは下記の記事が分かりやすいので読んでみて下さい。

CoffeeScriptでgeneratorがサポートされた

ECMAScript 6でサポートされるgeneratorは、V8で実装されました。
V8を使っているnode.jsでも、unstableバージョンで使用出来ます。
先述の通り、このgeneratorは新しい構文が必要なため、CoffeeScriptでは使えませんでした。
しかし長い議論の末、開発版でついにgeneratorが対応になりました!finally!

上記Pull Requestによると、function内にyieldキーワードがあると、自動的にgenerator(function*)に変換されるようです。

さっそく使ってみる

node.jsはバージョン 0.11.9 以上を用意して下さい。

開発版のCoffeeScriptをインストールします:

$ npm install --save git://github.com/jashkenas/coffeescript.git

以下に簡単な例を示します(a2z.coffee):

a2z = ->
  c = 97

  while (c < = 'z'.charCodeAt(0))
    yield String.fromCharCode(c++)

g = a2z()
i = 0
console.log ++i, g.next().value
console.log ++i, g.next().value
console.log ++i, g.next().value

以下のコマンドで実行します:

$ coffee --nodejs --harmony a2z.coffee
1 'a'
2 'b'
3 'c'

使えました!

koaをCoffeeScriptで書く

koa は、node.js用の次世代Webフレームワークです。
generatorの仕組みを活用しています。
CoffeeScriptのgeneratorサポートによって、koaもCoffeeScriptで書けるようになりました。
さっそく書いてみます。

app.coffee:

koa = require 'koa'
app = module.exports = koa()

app.use (next)->
  this.body = yield (cb)->
    cb null, 'hello, world'

app.listen 3000 if !module.parent

以下のコマンドで実行します:

$ coffee --nodejs --harmony app.coffee

http://localhost:3000/ を開いてみましょう。
hello, worldと表示されたら成功です!

今後の進化が楽しみですね。