カカリアスタジオブログ

Happy Elementsのゲームブランド「カカリアスタジオ」の公式ブログです。

coffeescriptを好きな8つの理由と4つのトピック

はじめに

エンジニアの@ryooo321です。 賛否両論ありますが、私はcoffeescriptには良い印象を持っており、積極的に使っています。 今回は私がcoffeescriptを好きな理由と、Source map、livescriptなどの周辺のトピックについても紹介できればと思います。

目次

coffeescriptを好きな8つの理由 ・4つのトピック -> Source mapでcoffeescriptのコードのままデバッグ -> 実行速度は早くはならない -> haskell風に書けるcoffeescript派生LiveScript -> ブラウザ実行

どんな方にcoffeescriptを薦めるのか

coffeescriptを採用するかはメンバーのスキルやプロジェクトの風土などによりケースバイケースだと思っています。 javascriptで満足しているなら、やらなくてよいと思います。 javascriptの下記の点に不満があるなら、coffeescriptを採用するメリットがあると思います。 ・javascriptの文法や特性に精通していないメンバーがいる。 ・javascriptのコーディング方法がメンバー間で揃わない。 ・大規模なプログラム群をjavascriptで書いている。 ・javascriptを書いていて楽しくない。

 

coffeescriptを好きな8つの理由

その1. 学習コストが少ない

javascriptpythonrubyを書ける方であれば、かなり簡単に習得できます。 (恐らく1時間もかからずざっと書けるようになるかと。)

 

その2. javascriptの罠を勝手に回避

coffeescriptで書くだけで、下記のようにjavascriptの罠を回避できます。 ・varのつけ忘れによるグローバル変数定義は、意図しなければ起きない ・定義箇所によっては意図しない挙動を引き起こす、関数・変数定義のホイスティングを回避 ・挙動が曖昧な弱い等価比較(==)は、厳密な等価比較に変換(===) ・ブラウザ間で挙動が変わるjavascript予約語を、自動でエスケープ ・文末セミコロンの省略やオブジェクト末尾カンマによるエラーを回避

 

その3. 出力するjsがとにかく綺麗

コンパイルで出力されるjavascriptはかなり綺麗で、そのままjavascriptで運用してもよいくらいです。 関数や変数の名前はそのまま出力されます。 単行のコメントはコンパイル時に削除され、ブロックコメントは残ります。 綺麗なので、coffeescriptがもしもオワコンとなっても、javascriptファイルだけで十分運用できるレベルです。

 

その4. 定型句が楽に書ける

class、継承、for文、デフォルト引数、可変長引数、変数バリデーションなど javascriptでよく使われる定型句が、coffeescriptシンタックス表現で楽に使えます。 coffeescript自体がjavascriptスニペット群であるかのように、綺麗で素直なjavascriptに変換してくれます。 ※ ステップ数はjavascriptの1/3などとも言われますが、実用上ではそんなに減ったことはありません。 私の場合ではせいぜい30%減ってところです。

 

その5. 楽しく書ける

インデントによる表現など無駄を省いたコーディングスタイルで、とにかくタイピングが楽です。 後置のif文
list.push(item) if item.price is 0
↓↓↓変換後↓↓↓
if (item.price === 0) list.push(item);
?による存在演算子
price = list["price"] ? 100
↓↓↓変換後↓↓↓
price = (_ref = list["price"]) != null ? _ref : 100;
関数のdefinedも確認できます。
# listが定義済みかつpush()が実装済みならitemをpushする
list?.push? item
↓↓↓変換後↓↓↓
if (typeof list !== "undefined" && list !== null) {
  if (typeof list.push === "function") list.push(item);
}
ファットアロー(=>)による実行コンテキストの固定化 javascriptでは関数のthisは実行コンテキストを指し示すので、「var self = this;」などと書いて関数の中ではselfを用いるのですが、coffeescriptでは簡単に回避します。
# 実行コンテキストに関わらずfunc内でのthisが常に自分自身のオブジェクトを指すように定義
class Hoge
  func: (name)=>
    this.name = name
↓↓↓変換後↓↓↓
var Hoge,
  __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

Hoge = (function() {

  Hoge.name = 'Hoge';

  function Hoge() {
    this.func = __bind(this.func, this);

  }

  Hoge.prototype.func = function(name) {
    return this.name = name;
  };

  return Hoge;

})();

 

その6. コンパイラをほとんど意識しないでよい

コンパイラの動きが直感的で、コーディング中ほとんど意識せず作業できます。 ファイルの変更を監視して自動でコンパイルするコマンドがあるので、編集後すぐにブラウザで確認できます。
coffee -wc hoge.coffee
また、Javascript Lintでの構文チェック(-l)や複数ファイルのjoin(-j)も自動でできます。 ブラウザではjavascriptデバッグすることになりますが、数千行程度のコードでも特に迷ったことはありません。

 

その7. レビューしやすい

javascriptの気をつけるべきポイントの多くをケアしてくれるので、レビュアーのチェックポイントはロジックを中心に集中できる。 ロジック以外のお作法的なコードが少ないので、理解しやすい。

 

その8. javascriptライブラリの選択肢が広がる

node.js界隈を中心に多くのライブラリがcoffeescriptで書かれています。 coffeescriptを学ぶことで間口が広がるかと思います。

4つのトピック

その1. Source mapsでcoffeescriptのコードのままデバッグ

概要(CoffeeScriptRedux)(いまいち) 私は特にjavascriptでしかデバッグできない現状に不満はないのですが、Source mapという仕組みでcoffeescriptのコードでデバッグが可能です。 Source mapはChromeデベロッパーツールの右下の設定から「Enable source maps」をonにすることで利用できます。
sss
こちらを使うとステップ実行やブレークポイントcoffeescriptのまま実行できます。
※ 公式のcoffeescriptでは現在未対応ですが、CoffeeScriptReduxというコンパイラで対応済みですので今回はこちらのコンパイラを使います。 ※ 現時点でCoffeeScriptReduxは複雑なCoffeeScriptファイルをコンパイルできませんでした。(条件未調査ですが平易なコードならコンパイルできましたというレベルです。) CoffeeScript Source Maps https://github.com/michaelficarra/CoffeeScriptRedux 仕組み coffeescriptファイル(.coffee)とjsファイル(.js)と、さらにマッピングファイル(.js.map)を用意することでcoffeescriptソースでデバッグできます。 ブラウザで読み込むファイルはこれまで同様jsです。 jsの最下部に「//@ sourceMappingURL=app.js.map」とmapファイルへのjsからの相対パスを記載します。 mapファイルは、CoffeeScriptReduxのcoffeeコマンドに--source-mapオプションをつけることで出力できます。
git clone git://github.com/michaelficarra/CoffeeScriptRedux.git
cd CoffeeScriptRedux
make deps
make test

npm install source-map
# jsの階層でコマンドを実行しなければ正しいファイルが生成されません。
cd jsの階層へ
./../CoffeeScriptRedux/bin/coffee --js -i app.coffee > app.js
./../CoffeeScriptRedux/bin/coffee --source-map -i app.coffee > app.js.map
(echo; echo '//@ sourceMappingURL=app.js.map') >> app.js

その2. 実行速度は早くはならない

coffeescriptjavascriptに1対1で変換される設計になっています。 そのため、javascript以上に早くはなれません。 超えることはできませんが、無駄のない高速なコードに変換してくれます。 比してjsxでは人の手では難しいレベルまで関数のインライン展開などの最適化を行ってくれるため、高速化されるとのことです。jsxについてはこちら http://jsx.github.com/

その3. haskell風に書けるcoffeescript派生LiveScript

coffeescriptからforkされたCocoからさらに派生したLiveScriptはhaskell風に書けるようです。 本家 http://gkz.github.com/LiveScript/ こちらのブログで紹介されています http://d.hatena.ne.jp/mizchi/20120706/1341568588

 

その4. ブラウザ実行

基本的にはサーバーサイドでコンパイルして、jsをブラウザで読み込むのですが、「coffee-script.js」を読み込むことで、ブラウザ側でコンパイルできます。

関連情報

CoffeeScript http://coffeescript.org/ ブラウザ上で実行できる環境と小さなチュートリアル集があります。 ここを一読すれば一通り理解できるかと思います。

・jsx http://jsx.github.com/

・LiveScript http://gkz.github.com/LiveScript/ http://d.hatena.ne.jp/mizchi/20120706/1341568588

一緒に働きたい方、絶賛 募集中 京都で開発してみたいというエンジニアの皆さん、ご応募お待ちしています! 技術力を伸ばしたい学生さん、アルバイトも可能なのでご応募お待ちしています! 大阪、滋賀、神戸から通勤実績あり
© Happy Elements K.K