Herokuでbuild時にGruntタスクを実行する

ども、小西です。

最近アプリ開発はもっぱらPlay2 + Gruntの環境で行っています。

Playにはassetsコンパイルの機能もあるので当初はそれを使っていたんですが、SinglePageAppの場合、どうしてもJavaScriptのコード量が大きくなるのでファイル分割とかしたくなるんですよね。

それで思い立ってGruntを導入したわけですが、これがなかなかいけてます。(^^v

勢い余ってGrunt超入門というスライドも書いたのでこれから導入される方はご参考に。

http://shunjikonishi.github.io/slides/grunt-introduction/index.html

今のところ使っているのは主にjsの連結、ミニファイ、文法チェックぐらいですが、おいおいその他のタスクも導入していきたいと思います。

ていうか、自分でなんかタスク作りたいなぁ。。。

watchが軽くて超絶便利なので、汎用タスク以外にもプロジェクト固有タスクを作るとか色々と使い道がありそうです。

★ Heroku連携での課題

さて、このPlay2 + Grunt開発。

ローカル開発時には特に不満はないんですが、Herokuで動かす場合には一つ大きな課題を抱えていました。

というのは、HerokuのbuildpackではGruntタスクが動くわけではないのでGruntで生成するファイル(連結とミニファイを施行したファイル)は、そのままだとSlugに含まれないのです。

この課題を解決するための一番安直な方法として昨日まではGitリポジトリにGruntで生成したファイルもコミットしていたんですが、この方法は本来バージョン管理の対象ではないファイルまでGitに含めることになるのでイマイチです。

理屈としてはカスタムbuildpackでbuild時にGruntを実行すれば良いだけなので、絶対誰かもう作ってる奴いるだろうと思って探してみたんですが

など、nodeやjavaの標準buildpackにGruntタスクの実行を追加したものは見つかりましたがscala版は見つかりませんでした。。。

ていうか、このやり方だと言語毎に専用のbuildpackが必要になるし、標準buildpack側に改修があった場合それに追随するのも面倒なのでイマイチだと思うんですよね。。。

このケースの場合buildpack-multiを使って標準のbuildpackとGruntタスクを実行するだけのbuildpackを自由に組み合わせることができた方が良いと思います。

★ 作ってみた

試しにbuildpackのmultiで

の二つを組み合わせてみたら問題なく、

  • build時にGruntタスクを実行し、
  • Dyno起動時にはscalaアプリを実行する(要Procfile)

アプリが作成できました。素晴らしい。(^^v

ただし、このままだとSlugの中に実行時には不要なNodeのランタイムが含まれてしまいます。(約30MB弱)

PlayのアプリはただでさえSlugサイズがでかいので、このオーバーヘッドは見逃せません。

なので、heroku-buildpack-nodejs-gruntをフォークして、

  • 明らかに不要そうな行をコメントアウト
  • 最後にnode_modulesフォルダと.npmフォルダを削除

しただけのbuildpackを作ってみました。

https://github.com/shunjikonishi/heroku-buildpack-with-grunt-task

buildpackの中身はあんまりちゃんと読んでないので、もうちょっと効率的な実装をすることも可能な気がしますけど、とりあえずちゃんと動いているようなので今回はこれでよしとします。

ご興味のある方は使ってみてくだされ。(^^v

コメント(0)