Sinatra AssetPackを試してみた

あるいは Kanazawa.rb meetup #23 に参加してきました。

何をしたかったか

  1. 現状では明らかに Rails に向いていないプロジェクトがある
  2. ホスティングはクラウドにしようと思うので、環境を先に決める必要がある
    • PHP でやるとか Ruby でやるとか
  3. 将来的には Rails で裏側をいじる必要あると思うんだけど、現状は表側だけで動けばいいし、Sinatra 使ってゴーじゃないか
  4. JS ヘビーになるし Sass も使いたいので Rails で言う Asset Pipeline 的なものは欲しい
  5. 「手間」は少なければ少ないほどよい

試した

  1. sprockets + sprockets-helpers
  2. sinatra-assetpack

Asset Pipeline が Sprockets を利用しているのは知っていたので Sprockets + Sprockets-Helpers がいちばん自分の既存の知識に近くて素朴な形になるんじゃないかと思って試してみたけど、結論から言うと自分の手には負えなかった。sprockets-helpers の提供する javascript_tag の展開するパスがどうしても思ったものにならない。 /assets/javascripts/application.js になってほしいのに /assets/application.js になったり /javascripts/javascripts/application.js になったり。中のコードをざっと眺めた感じでは正しく機能しそうに見えるんだけど。

実際に sprockets + sprockets-helpers でやってるというブログもいくつか見つけていたのだが、ダメだった。残念。

次に Sinatra AssetPack を試した。これは Rails の Asset Pipeline のようなものを Sprockets を利用せずに Sinatra 独自に実現するもの。後で気づいたけど、Sinatra のサイトで紹介されているのはこの方法なので、当然こっちの方がうまくいきやすそうである…。

Sinatra Recipes - Asset Management - Sinatra Assetpack

Sinatra AssetPack と Sprockets の比較

Sprockets は JavaScript ファイル、CSS ファイルの中に依存性を記述し、それを Sprockets が解決するという形なのだが、Sinatra AssetPack は Sinatra アプリ側に依存性を記述する。使い方としてはここがいちばん違う。書き方としてはこんな感じになる。

assets do
  serve '/assets/javascripts', from: 'assets/javascripts'

  js :app, '/javascripts/appication.js', [
    '/assets/javascripts/a.js',
    '/assets/javascripts/b.js'
  ]

  js_compression :jsmin
end

いろいろなJSライブラリを使いたいお

と思ったのならBowerを使うのがよさそう。

Bower

うーんイマドキ。

※ Rails には http://rails-assets.org/ という選択肢もあるけど、あれも結局 Bower 依存なので、Bower がいいんだろなという感じ。このように自分はすでに Rails で学んだ知識をもとにいろいろ類推して考える傾向にあるが、Rails にはいろいろな知が集まってくるので、この方法はとても効率がよいと考えている。Bower も名前は知っていてもピンと来ていなかったが、rails-assets のおかげで、ストンと理解できるようになった。

bower_components/ 以下の目的の JavaScript ファイルを上の依存ファイルの Array の中に納めてやればよい。

例えば jQuery 1.x を使いたかったら以下のような感じ。

bower.json

{
  "name": "myproj",
  "dependencies": {
    "jquery": "1.10"
  }
}

で、

bower install

これで試した時点で jQuery 1.10.2 が入る。

Sinatra AssetPack 側は以下のように bower_components も扱えるようにしてやる。

assets do
  serve '/assets/javascripts', from: 'assets/javascripts'
  serve '/bower_components',   from: 'bower_components'

  js :app, '/javascripts/appication.js', [
    '/assets/javascripts/a.js',
    '/assets/javascripts/b.js',
    '/bower_components/jquery/jquery.min.js'
  ]

  js_compression :jsmin
end

※ なんで 1.10 にしてあるかというと以下の production を試した時に 1.11 だとエラーになってしまうから。

Sinatra AssetPack でもう少し遊んでみて気づいたこと

  • rackup –env production で Asset Pipeline のように一つの JS にまとめてくれる
  • rake task も用意してあるので、いい具合に Rakefile に設定してやると rake assetpack:build が利用できる
  • rake assetpack:build すると coffee -> js 変換後のファイル、およびこれらを全部ひとまとめにした ファイルを生成してくれる
  • この生成済みのファイルがある場合はこれをそのまま serve してくれる
  • ない場合は動的に変換し、変換済みのコードをメモリにキャッシュして serve してくれる
  • jsmin は obsolete なので他のもの使った方がよいらしい

まとめ

とりあえずこれでフロントヘビーなプロジェクトでも手軽に PaaS に対応したサーバを用意しつつ、Rails の Asset Pipeline のように少ない手間で CoffeeScript や Sass などの恩恵に与ることができるようになった。よかった。

例えばこれが PaaS が node.js に対応しているならイマドキのフロントエンドっぽく全部 node.js で、bower + grunt

  • なんちゃらな感じで賄うこともできると思うんだけど、今回は Ruby か PHP というのが条件なので、Ruby を選択したうえでどうにかするという方針で調べた結果、Sinatra + Sinatra AssetPack という形になった。

結論 : 下手にググらずに本家ドキュメント読め。

More