新宿.rb#30で、僕はどうしてもlibsassが使いたかったんだ!というLTをした
ザックが来ていて、写真を撮ってもらえて浮かれた。
資料
www.slideshare.net
割りと赤裸々に、Libsass on Sprockets を実現するために苦しんだ話をさせてもらった。
これは西日暮里.rbでもLTさせてもらったsprocketsを捨てたい話の延長線の話で、gulpを使ってフロントエンドでビルドをした成果物(assets)をapp/assetsに配置する時の苦労話のstyle編。
具体的には
- 複数エントリーポイントの差分ビルドをどうやって実現するか
- asset_pathヘルパーをどうやって解決するか
の2つの問題があった。
複数エントリーポイントの差分ビルドをどうやって実現するか
これはproductionデプロイ時には関係なくて、開発時の悩みの話。
開発時のSprocketsさんは、依存関係を定義しておけば、リクエストされたタイミングでassetsを動的にコンパイルする。
styleに複数エントリーポイントがあってもなくても、リクエストされた段階で依存関係を解決して、assetsのurlを提供してくれる。
なのでファイルの変更を監視する必要はない。
しかしSprocketsさんに頼らずにgulpでビルドする場合には事前にビルドすることになるため、app/assetsに出力した段階で依存関係を解決しておく必要がある。
つまり、ファイルが変更されたタイミングでの再ビルドが必要になる。
コードベースが小さければ、大元のエントリーポイントを1つだけ設けて、全てビルドしてapp/assetsに配置すればいいのだけど、コードベースが大きくなってくると、1回あたりのビルド時間が長くなってしまう。
開発時にファイルの変更が入るたびに1s以上待つようになると、非常に苦痛で発狂しかねない。
ということで差分ビルドする必要がある。
そのためにはgulpタスク内でsassの依存関係(@import)を辿れるようにすればいい、ということでやってみたのが以下の記事。
最善策かどうかは置いといて、現状とりあえずうまく動いている。
asset_pathヘルパーをどうやって解決するか
sprockets外しで避けては通れない、asset_pathヘルパーをどうやって解決するか、という問題。
sprocketsはassetsファイルに変更があった場合には、ブラウザのキャッシュを効かせないため、ファイル名にdigestを付与する。
このdigestを無視して記述することができるのが、asset_pathヘルパーメソッドで、Sprocketsでruby-sassを使ってビルドする際には このヘルパーメソッドが使える。
だけどasset_pathはあくまでSprocketsの仕組みで、libsassには当然ないし、そもそもgulpでビルドした段階ではsprocketsのdigestを知ることはできない。
これをSprocketsのRailに乗っかったままどうやって解決するか、というのは下記の記事が参考になる。
しかし開発段階で、.css.erbなファイルにはしたくない。
影響範囲が大きいので、imageをpublicに配置するようにするのもどうかな。。
あとある事情で、どうしてもruby-sassを撲滅したい理由もあった。(つまり.scssなファイルはapp/assetsには置きたくない。(詳しくはLT資料を参考)
そのためにどうしたか、というのが以下のqiitaの記事。
簡単に言うと
gulpで無理やり.css.erbに変換するか。erbなら余計な処理もなくて軽いでしょ
という雑な対応。まぁうまく動いた。
これもっとかっこいい解決策あるだろ、という感じがする。
具体的にはsprocketsでcssのプロセッサーを自作すればいいのでは?と思っているのだけど、sprockets力が足りなくてそこまでには至っていません。
かっこいい解決策をお持ちの方は是非教えてください!
さいごに
新宿.rb、運営されてる方々、参加された方々お疲れ様でした!
次回以降も是非参加させていただきたいと思っています。
よろしくお願いします <(_ _)>