Ruby on Rails7ではWebpackerがデフォルトで無くなったらしい...
え?マジ?じゃあJavaScriptのバンドルとかどうすんの?
Rails7に触れる機会がなかったのでこの辺りの疑問をながらく放置してきたが、いい加減調べることにした。
何番煎じだい?という内容だが、2023年初頭時点で見えているものとして、まとめることに意味があると信じたい。
前提
対象読者
Rails7のフロントエンド周りに関して、大きく変わったらしいということは知っていてもそれ以上詳しいことは知らない人。
この記事の目標
個人的に 採用する Rails7のフロントエンド周りの選択を固める
まとめ
- importmap-rails
- Hotwire(turbo-rails + stimulus-rails)
- sprockets-rails
- tailwindcss-rails
を個人的には採用していこうと考えている。
これらの選択肢はRails7以降の方針にある程度合致し、かつ少なくとも個人開発レベルであれば問題なさそうという印象。
(業務だと...中小規模でもややチャレンジングかもしれない)
本文
大方針
まずRails7のフロントエンド周りに関しては、
DHHによる以下記事の内容を押さえておく必要がある。
要約すると、
- ブラウザにおけるES6のネイティブ対応
- HTTP/2の普及
- import mapsの登場
によってJavaScriptのバンドルやトランスパイルを使わなくてもモダンなWebアプリケーション開発ができる道筋が開かれてきているよね、という話。
これが実現できれば、BabelやWebpack等に関わる複雑なツールチェインは不要になる。もっと言えばNode.jsが不要になる。
Railsのフロントエンドは大まかにこの方向を目指しているようだ。
(その分かりやすい例の1つとしてWebpackerがデフォルトではなくなっている)
ただし以下のような懸念はある。
- React等トランスパイルを必要とするパターンは存在する。
- JavaScriptのエコシステムへの対応ができていない。
- UMDパッケージの考慮
- パッケージの更新/管理方法
この方針だとReactは使えないし、そうでなくてもJSのライブラリ周りは利用のハードルがかなり高くなる。
(業務では...という懸念はこの辺から)
JavaScript周りの具体的な話
その上でRails7におけるJavaScript周り(およびフロントエンド全体)の具体的な方針は以下で示されている。
こちらの記事で上記の日本語訳を記載してくれている
要約するとRails7のフロントエンドは大まかに3つの選択肢を提供している。
1つ目。これは前述のJSのバンドルやトランスパイルを使わない道。Webpackerの代わりにimport maps(importmap_rails) & Hotwireを用いる。
2つ目。従来通りWebpack等を利用してJSのバンドルやトランスパイルを行う道。ただしWebpackerは推奨されていないようだ。Rails7ではjsbundling-rails というgemが用意されており、esbuild, rollback, webpack等から自分で選択する。推奨されていないだけでWebpackerも利用はできる。ただし今後バージョンアップは行われなくなり、後継としてShakapackerが登場するらしい。
3つ目。Railsは単なるAPIとして機能する(いわゆるAPIモード)。フロントエンドは別に好きなものを用意する。
所感
一番手堅いのは 2つ目の選択肢(Webpack等)だろう。実績もあるし、React等のJavaScriptのライブラリを容易に用いることができる。業務を考えるとこちらを選ぶ人が多いように思う。
ただ個人的には今後のRailsの方向性を鑑みて 1つ目の選択肢(import maps & Hotwire)を選びたい。Hotwireに関してはあまり用いたことはないのだが、同僚からは業務で用いても案外使用感が良いという話も聞く。
これまでは少しでもリッチなUIであれば直ぐに Rails + Reactを採用していたが、内心ここまでする必要はあるのか?と疑問に感じていた部分もある。方針を撤回してしばらくHotwireを使ってみようと思う。
アセットパイプライン
Webpackerを使わないならSprocketsを使うのかというと、必ずしもそうでないようだ。
「大方針」に記載がある通り、Rails7(&それ以降)の方針としては「JavaScriptのバンドルやトランスパイル」は行わないことを目指している。これを前提とすると Sprocketsよりも劇的にシンプルで高速なアセットパイプラインを実現できる、らしい。
そのために作られているのがPropshaftだ。将来的にはSprocketsを置き換える存在になることが予想される。詳細は以下 PropshaftのREADME 日本語訳(ありがたい)参照。
ただこのPropshaftはbeta版レベルの状態らしい。直ぐにSprocketsと置き換えられるものでもなさそうだ。
Will Propshaft replace Sprockets as the Rails default?
Most likely, but Sprockets need to be supported as well for a long time to come. Plenty of apps and gems were built on Sprocket features, and they won't be migrating soon. Still working out the compatibility story. This is very much beta software at the moment.
(PropshaftはSprocketsに代わってRailsのデフォルトとなるのでしょうか?
その可能性は高いですが、Sprocketsも今後長い間サポートされる必要があります。たくさんのアプリやgemがSprocketの機能で作られていて、それらはすぐに移行することはないでしょう。互換性については、まだ検討中です。これは、現時点では非常にベータ版のソフトウェアです。)
所感
Propshaftはベータ版相当の存在でまだ利用例も多くなく採用にはリスクが高い。実は試しに使ってみたのだが、(プレーンな)CSSの利用で少し引っかかってしまった。情報もあまり出てこない。
Rails7のデフォルトでは sprockets-rails がインストールされるので、素直にそれに従うことにする。
CSS
最後にCSSについて。
rails new —help を実行すると以下のようなcssのオプションが確認できる。
c, [--css=CSS] # Choose CSS processor [options: tailwind, bootstrap, bulma, postcss, sass... check https://github.com/rails/cssbundling-rails]
さらに
より以下のような記載も確認できる。
Use Tailwind CSS, Bootstrap, Bulma, PostCSS, or Dart Sass to bundle and process your CSS
つまるところRails7ではCSSに関して、tailwind, bootstrap, bulma, PostCSS, Dart Sass(sass)が公式の選択肢として提供されている。(もちろんこのオプションを用いずプレーンなCSSを用いることもできる)
ただDHHはNodeを利用しない環境でのCSS利用例として、Tailwindを想定しているようで、tailwindcss-rails というGemも別途用意している(DHHのコメントも参照)。実際Tailwindを用いたRails7のAlpha Previewも公開されている。これらCSS関連の選択肢では、Tailwindがやや目立つ立ち位置にいる。
所感
DHHはTailwindを推奨している...っぽい(?)。
Nodeを使わない環境を目指していることも考えてもひとまず tailwindcss-rails を使うのが良さそうかな...?
まとめ
最後にまとめ。
- Rails7(およびそれ以降)のフロントエンドは、JavaScriptのバンドルやトランスパイルを使わない = Node.js レスな環境を目指している
- import-rails, Hotwireの組み合わせにより実現
- 同時にWebpack等を前提としたこれまで通りの選択肢も用意している
- アセットパイプラインに関しては上記方針を踏まえてPropshaftが新しく登場しているが、やや時期尚早の雰囲気。
- CSSは複数の選択肢が提供されている。その中でTailswind CSSが少し推されているように見える
個人的には
- JavaScript周りはimport-rails & Hotwire
- アセットパイプラインは素直にsprockets-rails
- CSSはtailwindcss-rails
を採用しようと思っている。
これでモダンなWebアプリが本当にできるかは…やってみないと分からない。ただBasecampはこれでうまくやっているというのだから、多くの場合はなんとかなるのだろう。今後個人開発や社内ツールで試していきたいところ。
おまけ
実はこの記事の内容は以下の議論を読めば事足りる。むしろこっちのが詳しい。(この記事の意味とは)