他ライブラリとの組み合わせ
下記の歴史については私もよくわからないところがありますので、参考程度と考えてください
Ruby on RailsはGoogle V8エンジンやnode.jsよりも古いフルスタックフレームワークで、昔から積極的にJavaScriptやCSSのビルド技術を取り入れていました。
特にSprocketsは歴史が古く、少なくとも2011にリリースされたRails 3.1にRails Guideがありました。この頃はCSS, SASS, JavaScript, CoffeeScriptのビルドに使用されていました。Webpackはまだ登場していませんでしたので、CSSやJavaScriptの中にERBのタグを入れるやり方は当時は必要でした。
例えば下記のような書き方は(今では非常に気持ち悪がられますが)よく見かけました。
.class { background-image: url(<%= asset_path 'image.png' %>) }
$('#logo').attr({ src: "<%= asset_path('logo.png') %>" });
その後、アプリっぽいJavaScript (React等)の処理はSprocketsからWebpackに委譲され、SprocketsとWebpackを繋げるのがWebpackerが使われるようになりました。WebpackerはCSSや画像のビルド等にも使用できました。
2021年のRails 7以降は、Webpackerではない新しいJavaScriptのビルド方法が採用されました。大きく3種類用意されています。
CSSについてはSASS等を使わずに生のCSSを使う方法がデフォルトとして用意されています。最新のCSSはネスト化された定義やCSS変数など、従来はSASSがなければ実現できなかった機能が最初から用意されています。以前に比べて、大きいプロジェクトであっても生のCSSが現実的に使えるようになっています。
Tailwind CSSやSASSを使うのであれば、CSSをビルドするツールが必要になります。Tailwind CSSについては別個のtailwindcss-rails gemが用意されていますし、SASSを使いたいのであればdartsass-rails gemが用意されています。またJavaScriptビルド時にどっちみちNode.jsを使っていたのであれば、それを使うcssbundling-rails gemが用意されています。すべて公式のgemです。
tailwindcss-rails gemおよびdartsass-rails gemはNode無しで使えるのに対して、cssbundling-rails gemはNodeを必要とするぐらいの違いです。(ビルド用のDockerコンテナにnodeをインストールするところだけが面倒ですが、そこもさまざまにオプションを変えながらrails new
で生成されるDockerfileを参考をみて、それをコピペすれば対応できます)
本サイトでは、Reactを使う関係でどうしてもNodeを使用しますので、ついでにTailwind CSSもcssbundling-rails gemでビルドさせています。Reactを使わずに、またJavaScriptはimport mapsにするのであれば、私もtailwindcss-rails gemを使用したかもしれません。
非常に長い歴史を持つSprocketsでしたが、ノービルドが可能になったこと、およびJavaScript, CSS周りのエコシステムが充実してことを受けて、だんだん役割が狭まってきました。最初はJavaScriptのビルド、CSSのビルド、そしてdigestの付与等の役割を担っていたのが、今ではdigestの付与ぐらいしか役割がなくなってしまいました。そこで登場したのがPropshaftです。
Propshaftはdigestの管理が主な仕事になります。ERBを使った気持ち悪い手段を取らなくてもCSSやJavaScriptからアセットファイルを参照できますし、esbuild等がすでにdigestをつけてくれるのならば、propshaftが二重にdigestをつけるのを防ぐこともできます。
このようにRails 7, 8でRailsのアセット管理は大きく見直されました。ノービルドでやる場合であっても、あるいはReact/JSXを使ってJavaScriptをビルドする場合であっても、アセット管理は大幅に簡略化されています。
特にフロントエンドエンジニアに嫌われていたのは、Webpackerによる独自のRailsとの統合だったのではないかと思います。これを嫌ってReact/VueフロントエンドとRailsバックエンドのリポジトリを完全に分けていたプロジェクトも多いかと思います。しかし今のRailsはフロントエンドのエコシステムとより親和性のある方法を採用しています。
SprocketsやWebpackerがどうしても必要だった時代はもう過ぎ去りました。新しいツールと簡素な管理で、今まで以上に充実したアセット管理ができるようになったと言えるでしょう。