Attention! Translated article might be found on my English blog.

2015年11月10日火曜日

cakeで複数のCoffeeScriptファイルを1つにまとめる

CoffeeScriptのバージョンは1.9.1です。
クラスごとにファイル分けしようと思い色々調べてみました。
make, Makefileに相当するcake, Cakefileを使用し自動化するのが良いようです。

Cakefile作成

Cakefileを使用しcoffeescriptをビルドする | com4tisで紹介されているCakefileをコピーし、自分用にアレンジしました。
とりあえずこんな感じです。なるべく短いのを目標に。

# original: http://com4tis.net/2012/12/05/cakefile-coffeescript-bulid/

fs   = require 'fs'
exec = require('child_process').exec
util = require 'util'

# 設定
OPTIONS = '-cb --stdio'
SRCDIR = '.'    # *.coffeeファイルがあるディレクトリへのパス
OUTDIR = '.' # *.jsファイルの保存先
TARGET_FILENAME = 'script.js'

# coffeeフォルダ内のCoffeeScriptを列挙
targetList = []
for f in fs.readdirSync SRCDIR
  targetList.push RegExp.$1 + '.coffee' if f.match /^(\w+)\.coffee$/

task 'build', 'compile target files', ->
    targetList = targetList.join(' ')

    # コンパイルコマンド
    cmd ="cat #{targetList} | coffee #{OPTIONS} > #{OUTDIR}/#{TARGET_FILENAME}"

    # コンパイル実行
    exec cmd, (error, stdout, stderr) ->

        util.log(error) if error
        util.log(stdout) if stdout
        util.log(stderr) if stderrりあえずこんな感

注意点は
  • 正規表現でヒットした文字列に.coffeeを付けるようにした
  • -jオプションをやめ、catで繋げてパイプとリダイレクトで入出力するようにした
あたりです。
前者に関しては、参考スクリプトそのままではコンパイル時にcoffeeファイルを見つけられず失敗してしまっていました。
後者に関しては、-jオプション有りでも成功しますが、ログに

The --join option is deprecated and will be removed in a future version.

If for some reason it's necessary to share local variables between files,
replace...

    $ coffee --compile --join bundle.js -- a.coffee b.coffee c.coffee

with...

    $ cat a.coffee b.coffee c.coffee | coffee --compile --stdio > bundle.js

と表示されていたので、推奨されている方法に変更してみました。
この場合--stdioというオプションを付けないとインタラクティブモードに対してstdinを流してしまうようなのでご注意を。
リダイレクト使っちゃうとcoffeeコマンドでエラーが出た場合Cakefile内で検知できるんだろうか…。
あと-bオプション有りでも大丈夫なのかが気になるところ。
まだとりあえずコンパイルできた段階なのでその辺よくわかりません。

jsファイル生成

$ cake build

でイナフ。

ちなみに余談ですが、Cakefile中のインデントでスペースとタブが混在していると
コンパイル時にエラーになるようなので注意してください。
vimだと:set expandtab (:set et)で切り替えると良いです。