JSビルドツールをRakeで組むことにした


フロントエンドでいろいろ組むWebサイトを作ることになったのですが、いちいち手動ビルドしていては日が暮れるので、ビルドツールも用意することにしました。ただし、よく使われるようなGruntやgulpではなく、Rakeを選択しました。

フロントエンド側のビルドツールの必要性

JavaScriptを補助的にしか使わないようなWebサイトであれば、jQueryを読み込んでちょこちょこ、程度で済むのですが、フロントエンドフレームワークを使うとか、あるいはフロントエンド側でバリバリ計算させるような形で作るとなると、とたんに困ることが出てきます。いちばん大きなこととしては、JavaScriptにモジュール化やその依存管理の機能がないので、そのままではファイル分割すら複雑になってしまう、ということがあります。

また、直接JavaScriptで書くのでなくAltJSで書くとか、あとはファイルの結合・ミニファイなど、ブラウザで使うJavaScriptを生成するためには、前後にいくつかのプロセスが必要となっています。

ということで、手動でやるには混沌としすぎるので、効率的な開発にはこれらの自動化が欠かせなくなってきます。

はやりのツール…でも、疑問が

そんなWebまわりのビルドツールを回すためのツールとして、Gruntやgulpなどが最近はよく使われています。自分自身も使おうとして調べてみたのですが、2つほど「これでいいのかな?」と思う点が出てきました。

枯れていない

去年はGruntがもてはやされていたところが、今年はgulpに移っているというように、開発ツールとして使うには世代交代が速すぎる印象を受けました。もちろん、「新たなAltJSであるHogeScriptを使うために、そのコンパイラのhogecを入れる」というような変化は必要かもしれませんが、「hogecが現在使用中のビルドツールに対応していないので、つなぐ部分を自分で作る or ビルドツールを乗り換える」というような、本質的でない手間はできれば事前に回避したいものです。

掛け合わせで増えていくプラグイン

Gruntやgulpで何かしらの処理系を使うには、それ用のプラグインが必要になってきます。となれば、「使うツール×使われるツール」の掛け算でプラグインが増えていくわけですが、そのように増え続けたプラグインの中には、保守が不十分なものや、ひどいときには組み合わせとして存在しないこともあります。これまた、エコシステムを不安定化させる要因となってしまいます1

古い問題に、枯れ果てたツール

このような、「ビルド時の依存関係を解決する」という問題は昔からあるのですが、そのためのツールとしてmakeがあります。たしかに、makeのようなファイル単位での処理管理というのは悪くはないのですが、Makefileはお世辞にも書きやすいものではなく、また本体での機能で足りない部分はシェルを呼ぶことになるので、これまた慣れていないと極端に使いづらいものです。

適度に枯れて、でも活発なRake

そこで注目したのが、Rubyに付いてくるRakeです。Rakefileは通常のRuby+Make的な依存関係処理のためのDSLからなっていて、もともとRubyistであればすんなりと書けるものでした。そこで、

  1. 生成するJavaScriptは、一時フォルダのJavaScriptからbrowserify | uglifyjsで生成する。
  2. 一時フォルダのJavaScriptは、(あれば)ソースフォルダの*.jsファイルからbabelで生成する。
  3. 一時フォルダのJavaScriptは、(あれば)ソースフォルダの*.coffeeファイルからcoffeeで生成する。

というように、「このファイルを生成するのに何が必要」ということを宣言的に書けば、あとはRakeが処理してくれます。また、すべてコマンドラインツールを呼び出して処理して、パイプあるいはファイル生成して次のステップに渡すので、「プラグインガー」なんてことも起きません(さすがに、コマンドラインから呼べないツールが生まれることは考えづらいですし)。そして、タイムスタンプを見て必要な処理だけを行う、Make譲りの判定機能も健在です(いざとなれば rake cleanもできるようにしてあります)。


  1. BrowserifyにもCoffeeifyやBabelifyのように他ツールと連携するプラグインがありますが、同様の理由で使わないことにしています。