新宿.rb#30で、僕はどうしてもlibsassが使いたかったんだ!というLTをした

ザックが来ていて、写真を撮ってもらえて浮かれた。

instagram.com

資料

www.slideshare.net

割りと赤裸々に、Libsass on Sprockets を実現するために苦しんだ話をさせてもらった。

これは西日暮里.rbでもLTさせてもらったsprocketsを捨てたい話の延長線の話で、gulpを使ってフロントエンドでビルドをした成果物(assets)をapp/assetsに配置する時の苦労話のstyle編。

具体的には

  1. 複数エントリーポイントの差分ビルドをどうやって実現するか
  2. asset_pathヘルパーをどうやって解決するか

の2つの問題があった。

複数エントリーポイントの差分ビルドをどうやって実現するか

これはproductionデプロイ時には関係なくて、開発時の悩みの話。

開発時のSprocketsさんは、依存関係を定義しておけば、リクエストされたタイミングでassetsを動的にコンパイルする。
styleに複数エントリーポイントがあってもなくても、リクエストされた段階で依存関係を解決して、assetsのurlを提供してくれる。
なのでファイルの変更を監視する必要はない。

しかしSprocketsさんに頼らずにgulpでビルドする場合には事前にビルドすることになるため、app/assetsに出力した段階で依存関係を解決しておく必要がある。
つまり、ファイルが変更されたタイミングでの再ビルドが必要になる。

コードベースが小さければ、大元のエントリーポイントを1つだけ設けて、全てビルドしてapp/assetsに配置すればいいのだけど、コードベースが大きくなってくると、1回あたりのビルド時間が長くなってしまう。
開発時にファイルの変更が入るたびに1s以上待つようになると、非常に苦痛で発狂しかねない。
ということで差分ビルドする必要がある。

そのためにはgulpタスク内でsassの依存関係(@import)を辿れるようにすればいい、ということでやってみたのが以下の記事。

qiita.com

最善策かどうかは置いといて、現状とりあえずうまく動いている。

asset_pathヘルパーをどうやって解決するか

sprockets外しで避けては通れない、asset_pathヘルパーをどうやって解決するか、という問題。

sprocketsはassetsファイルに変更があった場合には、ブラウザのキャッシュを効かせないため、ファイル名にdigestを付与する。

このdigestを無視して記述することができるのが、asset_pathヘルパーメソッドで、Sprocketsでruby-sassを使ってビルドする際には このヘルパーメソッドが使える。

だけどasset_pathはあくまでSprocketsの仕組みで、libsassには当然ないし、そもそもgulpでビルドした段階ではsprocketsのdigestを知ることはできない。

これをSprocketsのRailに乗っかったままどうやって解決するか、というのは下記の記事が参考になる。

qiita.com

しかし開発段階で、.css.erbなファイルにはしたくない。
影響範囲が大きいので、imageをpublicに配置するようにするのもどうかな。。
あとある事情で、どうしてもruby-sassを撲滅したい理由もあった。(つまり.scssなファイルはapp/assetsには置きたくない。(詳しくはLT資料を参考)

そのためにどうしたか、というのが以下のqiitaの記事。

qiita.com

簡単に言うと

gulpで無理やり.css.erbに変換するか。erbなら余計な処理もなくて軽いでしょ

という雑な対応。まぁうまく動いた。

これもっとかっこいい解決策あるだろ、という感じがする。

具体的にはsprocketsでcssのプロセッサーを自作すればいいのでは?と思っているのだけど、sprockets力が足りなくてそこまでには至っていません。

かっこいい解決策をお持ちの方は是非教えてください!

さいごに

新宿.rb、運営されてる方々、参加された方々お疲れ様でした!
次回以降も是非参加させていただきたいと思っています。
よろしくお願いします <(_ _)>