CoffeeScriptプロジェクトのコンパイルを自動化

CoffeeScriptは、エレガントな文法で処理を記述できる反面、実行前にコンパイルが必要という手間がある。

単に動作確認を行うだけであれば、CoffeeScriptの動作確認や学習を手軽に行う方法で紹介したように、対話型実行モードでcoffeeコマンドを実行してやればよかった。

 

実際に何か作ろうとプロジェクトを作成したときは、CoffeeScriptでコードを書いて、動作確認前に毎回coffee --compileコマンドを実行する必要がある。

しかし毎回コンパイルを手作業でするのは面倒なので、.coffeeスクリプトが更新されたタイミングで.coffeeから.jsへ自動的にコンパイルするようにする方法を紹介する。

 

CoffeeScriptでは、coffeeコマンドだけでこの機能を提供しているので、今回紹介する内容も、CoffeeScript本家に記載してある内容だけで構築されていたりする。

--bareオプション

プロジェクトの構成とコンパイル自動化の話題に入る前に、少し話は逸れるが、--bareオプションについて紹介しておく。

通常、coffee --compileコマンドで.coffeeファイルをコンパイルした.jsファイルは、top-levelの名前空間が名前汚染されないように、全てのコードが()で囲まれたコードが生成される。

 

例えば、SampleClassというクラス宣言をするプログラムをCoffeeScriptで記述して、コンパイルする。

 

するとこのように、生成されたコード全体が「(」と「)」で囲われたJavaScriptが生成される。

これは、CoffeeScriptが、不要なtop-levelの名前空間を汚染しないようにするための配慮だが、このような宣言になっていると、()で囲われた外からは、ここで宣言したSampleClassを参照することはできない。

 

例えば、このコードは、21行目でSampleClassクラスが参照できないため、エラーになる。

 

ファイルが別になっているようなコードからも参照することはできないため、.coffeeファイルを複数に分けて記載する場合には都合が悪い。

 

SampleClassを他の.coffeeファイルから参照できるようにしたい場合、--bareオプションをつけてコンパイルする。

--bareオプションを付けてコンパイルした結果のJavaScriptコードを確認すると、「(」と「)」は付加されていないことが確認できる。

このように、定義したクラス等を外部から参照したい場合には、--bareオプションを利用してコンパイルする必要がある。

 

今回の記事では、top-levelの名前空間汚染についてはあまり気にしないで、とにかく実践的な内容にしたいため、--bareオプションは常に使用してコンパイルするようにする。

プロジェクトの構造

まず、今回の記事で、CoffeeScriptのコンパイルを自動化するプロジェクトは、ここに示すような構造になっていることにする。

ProjectRoot
  |-index.html
  |-coffee
  | |-script1.coffee
  | |-script2.coffee
  |
  |-js

coffeeフォルダにCoffeeScriptのソースファイルであるscript1.coffeeとscript2.coffeeが入っているとする。

これらの.coffeeファイルをコンパイルして、jsフォルダに格納したい。

coffeeコマンドを実行するときのカレントディレクトリはProjectRootとする。

--outputオプション

coffee --bare --compile coffee

とすると、coffeeフォルダ内にある.coffeeファイルを全てコンパイルする。

このコマンドを実行した場合、コンパイルした.jsファイルは、.coffeeファイルがあるフォルダにそのまま作成される。

ProjectRoot
  |-index.html
  |-coffee
  | |-script1.coffee
  | |-script1.js
  | |-script2.coffee
  | |-script2.js
  |
  |-js

 

そうではなくて、.jsファイルはjsフォルダに出力したい。

その場合は、--outputオプションを利用することで、出力フォルダを指定することができる。

 

coffee --bare --compile --output js coffee

このコマンドを実行した場合、コンパイルした.jsファイルは、jsフォルダの下に作成されるようになる。

ProjectRoot
  |-index.html
  |-coffee
  | |-script1.coffee
  | |-script2.coffee
  |
  |-js
  | |-script1.js
  | |-script2.js

 

注意してほしいのは、コンパイルする.coffeeファイルが入ったフォルダの指定は、一番最後にするという点。

--outputオプションの直後に、.jsの出力フォルダを指定する。

逆のほうがしっくりくるんじゃ?と思うのは、私だけだろうか・・。

--watchオプション

今回の記事の主役は、この--watchオプションだ。

このオプションを利用すると、.coffeeファイルを監視し、ファイルが更新される度に自動的にコンパイルを行なってくれる。

 

>coffee --bare --watch --compile --output js coffee
EBUSY, open ‘K:\home\tmp12\StudyCoffee\js\script1.js’
00:08:14 – compiled coffee\script2.coffee
00:08:53 – compiled coffee\script1.coffee

以降、[Ctrl – C]キーストーロークで停止するまで、coffeeフォルダを関し続けてくれる。

 

ちなみに、coffeeコマンドの引数名は、プレフィクス--から-にして、最初の1文字に省略することができる。

例えば、--compileなら-cと記述できる。

 

これを使って短縮すると

>coffee -bwc -o js coffee
EBUSY, open ‘K:\home\tmp12\StudyCoffee\js\script1.js’
00:08:14 – compiled coffee\script2.coffee
00:08:53 – compiled coffee\script1.coffee

といった具合に短縮して記述することができる。

 

これで、.coffeeファイルの内容を変更した時に、自動的に.jsファイルにコンパイルする仕組みが用意できた。

 

この構成だと、index.htmlからは、

として、コンパイルしたそれぞれの.jsファイルを読み込み宣言しなければならない。

これはhtmlのソース的にすっきりしないので、大抵の人は、.coffeeファイルは複数でも、.jsファイルは1つにまとめたくなるんじゃないかと思う。

出力する.jsファイルを1つにまとめる

出力する.jsファイルを1つにまとめるには、--joinオプションを利用する。

先ほど紹介したコンパイルの自動化コマンドに、さらにコンパイルしたファイルをscript.jsに統合する場合は、次のようなコマンドになる。

>coffee -bwc -j js/script.js coffee
00:20:25 – compiled js/script.js

 

これを実行すると、jsフォルダの下に、script1.coffeeのコンパイル結果とscript2.coffeeのコンパイル結果が統合された、script.jsファイルが作成される。

ProjectRoot
  |-index.html
  |-coffee
  | |-script1.coffee
  | |-script2.coffee
  |
  |-js
  | |-script.js

 

こうすれば、index.htmlからは

として、1つのJavaScriptファイルのみを読みこめばいいようになる。

コメントを残す

トラックバック: http://pgnote.net/wp-trackback.php?p=722