Coffeescriptでクライアントサイドでビルド/テストの設定諸々メモ

CoffeeScript/Canvasでゲーム作ってて、結構巨大なプロジェクトになってしまったので色々工夫していた。

単体のとき

EmacsVim使ってるなら shadow.el/shadow.vim を使う

自分はemacsなのでshadow.elを入れた。
mooz/shadow.el - GitHub

(require 'shadow)
(add-hook 'find-file-hooks 'shadow-on-find-file)
(add-hook 'shadow-find-unshadow-hook
          (lambda () (auto-revert-mode 1)))

hoge.js.shd(CoffeeScriptとして記述)

## coffee -csb
f = (x) -> x + 1
f2 = (x) -> x + 1
print f 10
# Local Variables:
# mode: coffee
# End:

hoge.jsバッファは auto-revert-modeでリアルタイムに反映される。二画面分割で。

単体 超手抜きVer

とにかく動かす
CoffeeScriptはインストールしなくてもブラウザ上で実行できるよという話 - ariyasacca(2011-02-21)

sandbox.html

<!DOCTYPE html>
<html lang=ja>
<head>
  <title>test </title>
  <meta chaset=utf-8 />
  <script type="text/javascript" src="http://jashkenas.github.com/coffee-script/extras/coffee-script.js"></script>
</head>
<body>
  <script type="text/coffeescript">
# Coffee Script Sandbox
window.onload = -> 
   console.log "Hello!"

  </script>
  <canvas id="game" style="background-color:black;"></canvas>
</body>
</html>

CoffeeScript プロジェクト版 build.sh

わかった気になるJS開発手法
「200行超えたjsはメンテされないので分割してMakefile書け」とのことだったが、Makefileよくわからないのでshellscriptで書いた。

概要

coffeescriptをモジュールごとに分割して連結するシェルスクリプト書いた。
そんでQUnit使わずローカルでnodeのテストフレームワークVowsでローカルでテストを完結したくなった
=> 分割したファイルを連結するとき、ブラウザ依存コードとテストコードを切り離しておけばいいのでは?


build.sh

#!/bin/sh

SRC_DIR=src
DIST_DIR=build
TEST_DIR=test
TARGET="core char scenes"
TARGET_EXEC="browser"
TARGET_TEST="test"
BUILDOUT=all.coffee
BUILDOUT=all.js
TEST_BUILDOUT=test_all.coffee
TEST_BUILDOUT_JS=test_all.js

echo ========== build ==========
echo "##" ${BUILDOUT} "##" > base.coffee
for name in $TARGET; do
    echo ${SRC_DIR}/${name}.coffee to ${DIST_DIR}/${name}.js
    coffee -c ${SRC_DIR}/${name}.coffee
    mv ${SRC_DIR}/${name}.js ${DIST_DIR}/
    echo "# generated by "${SRC_DIR}/${name}.coffee >> base.coffee
    cat ${SRC_DIR}/${name}.coffee >> base.coffee
done
cat base.coffee $SRC_DIR/$TARGET_EXEC.coffee > $DIST_DIR/$BUILDOUT
cat base.coffee $SRC_DIR/$TARGET_TEST.coffee > $TEST_DIR/$TEST_BUILDOUT
rm base.coffee
coffee -c $DIST_DIR/${BUILDOUT}

if [ "$1" = "test" ]; then
    echo ========== test ===========
    coffee -c $TEST_DIR/${TEST_BUILDOUT}
    node $TEST_DIR/${TEST_BUILDOUT_JS}
fi


例えばこんな構成で

build.sh (+x)
src/
   core.coffee
   char.coffee
   scenes.coffee
   browser.coffee    # publish for html
   test.coffee    # test code
build/
   + all.coffee
   + all.js
test/
   + test_all.coffee
   + test_all.js

$ ./build.sh で 単体ファイルのall.jsを作る。


browser.coffee にはブラウザ依存のコード(window.onloadとか)を書く。
test.coffee にはnodeとvows依存のテストコードを書く。

test.coffeeのサンプル
// ここだけnode,vowsに依存
vows = require 'vows'
assert = require 'assert'

vows.describe('Game Test').addBatch
  'combat test':
    topic: "atack"
    'test': ()->
      p = new Player 320,240
      e = new Enemy Math.random()*640 ,Math.random()*480

      while p.state.alive and e.state.alive
        p.atack(e)
        e.atack(p)
.export module

テスト時は ./build.sh test


.export module がキモだそうです
参考: coding as drawing: Vows で クライアントサイドの CoffeeScript / JavaScript のテストをする時の Tips


ところどころ手抜きだけど、これで割と快適。