CoffeeScript付属の軽量ビルドツールcakeを使ってみる
CoffeeScriptにCakeというビルドツールが付属している。
RubyでいうところのRakeみたいなものだが、Rakeよりは機能が小さい。Rubyを使いこなせる人はRakeを使えばいいと思う。
makeでMakefileを、rakeでRakefileを用意してその中にtaskを記述するように、cakeでもCakefileというのを用意する。
$ tree . |-- Cakefile `-- src |-- coffee | |-- intro.coffee | |-- main.coffee | `-- outro.coffee `-- js 3 directories, 4 files
ここではintro.coffee、main.coffee、outro.coffeeをくっつけて一つのCoffeeScriptとしてsrc/js/main.jsにコンパイルするタスクは次のようになる。
fs = require 'fs' {exec} = require 'child_process' util = require 'util' srcCoffeeDir = 'src/coffee' targetJsDir = 'src/js' targetFileName = 'main' targetCoffeeFile = "#{srcCoffeeDir}/#{targetFileName}.coffee" targetJsFile = "#{targetJsDir}/#{targetFileName}.js" coffeeOpts = "--output #{targetJsFile} --compile #{targetCoffeeFile}" coffeeFiles = [ 'intro' 'main' 'outro' ] task 'build', 'Build single JavaScript file from source files', -> util.log "Building #{targetJsFile}" appContents = new Array remaining = coffeeFiles.length util.log "Appending #{coffeeFiles.length} files to #{targetCoffeeFile}" for file, index in coffeeFiles then do (file, index) -> fs.readFile "#{srcCoffeeDir}/#{file}.coffee" , 'utf8' , (err, fileContents) -> util.log err if err appContents[index] = fileContents util.log "[#{index + 1}] #{file}.coffee" process() if --remaining is 0 # (***) process = -> fs.writeFile targetCoffeeFile , appContents.join('\n\n') , 'utf8' , (err) -> util.log err if err exec "coffee #{coffeeOpts}" , (err, stdout, stderr) -> util.log err if err message = "Compiled #{targetJsFile}" util.log message fs.unlink targetCoffeeFile, (err) -> util.log err if err
シェルでcakeとだけ入力すると、登録されているtaskとその詳細が出力される。
$ cake
cake build # Build single JavaScript file from source files
cake nameでtaskを起動する。
$ cake build 22 Jan 22:42:43 - Building src/js/main.js 22 Jan 22:42:43 - Appending 3 files to src/coffee/main.coffee 22 Jan 22:42:43 - [1] intro.coffee 22 Jan 22:42:43 - [2] main.coffee 22 Jan 22:42:43 - [3] outro.coffee 22 Jan 22:42:43 - Compiled src/js/main.js
一つだけ注意点があって、(***)という部分でわざわざprocess関数をコールバック関数内で実行しているのは、node.jsではIOがノンブロッキングだからです。node.jsのnode.jsたる所以ですね。