cakeを使ってcoffeeファイルが変更されたら自動で再コンパイルさせる
node.jsのドキュメントを眺めていたらfs.watchとfs.watchFileというのを見つけた。それぞれファイル名やディレクトリ名を渡すと、それが更新されるとコールバックを起動してくれる関数みたい。
前回の記事で、cakeを使ってビルドするtaskを作ったので、ファイルを監視して、それが変更されたら自動で再コンパイルするtaskを追加してみる。
前回の記事のCakefileの末尾に次のコードを追加する
task 'watch', 'Watch source files and build changes', -> util.log "Watching for changes in #{srcCoffeeDir}" fs.watch srcCoffeeDir, (event, filename) -> util.log "Saw change in #{srcCoffeeDir}/#{filename}" invoke 'build' # build taskを起動する
このタスクを起動するには
$ cake watch 22 Jan 23:24:53 - Watching for changes in src/coffee
ターミナルをもう一つ立ち上げるなどして、src/coffee内のファイルを変更すると
22 Jan 23:25:08 - Saw change in src/coffee/undefined 22 Jan 23:25:08 - Building src/js/main.js 22 Jan 23:25:08 - Appending 3 files to src/coffee/main.coffee 22 Jan 23:25:08 - [1] intro.coffee 22 Jan 23:25:08 - [2] main.coffee 22 Jan 23:25:08 - [3] outro.coffee 22 Jan 23:25:08 - Compiled src/js/main.js
とbuild taskが起動されて、ログが見れる。ここで、一番上がSaw change in src/coffee/undefiedになっているのが問題で、コールバックのfilenameが正しく渡されるのはWindowsとLinux環境だけで、OSXだとundefinedが渡される。今後解決するらしいけど。
なので、ここではfs.watchではなく、fs.watchFileを使うことにした。以下のように変更
task 'watch', 'Watch source files and build changes', -> util.log "Watching for changes in #{srcCoffeeDir}" for file in coffeeFiles then do (file) -> fs.watchFile "#{srcCoffeeDir}/#{file}.coffee" , (curr, prev) -> if +curr.mtime isnt +prev.mtime util.log "Saw change in #{srcCoffeeDir/#{file}.coffee" invoke 'build'
これで問題なくログにどのファイルの変更を検知して再コンパイルを行なっているのかが表示される。