一通りHotwireを学習したものの、全体の構成がいまいちピンとこない人のために大局的に解説します。
Reactや他のモダンフロントエンドと異なり、Hotwireはブラウザ技術を代替するものではありません。あくまでもブラウザ技術の拡張を目指しています。静的HTML, PHPやERB, Bladeなどをはじめとした従来のフロントエンドに対して、インタラクティブなUIを作りやすくするための拡張が用意されています。
既存のERBページをHotwire化する際も、最初にERBのページを作り、それからどうやってインタラクティブにするかを考えます。Reactではウェブページの作り方をひっくり返し、ステートから出発しているのとは対照的です。Hotwireは普通にHTMLのウェブページから出発します。
Hotwireは大きく3つの側面で従来のHTMLを拡張しています。ここではウェブページを作ることに主眼を置きますので、最初のTurboとStimulusについてのみ紹介します。
TurboはほとんどJavaScriptを書かなくとも非同期的にページを部分更新する技術です。
Ruby on Railsは2004年の誕生以来、AJAXに注力しており、非同期的にページを部分更新する技術をフレームワークの中に取り込んでいました。
2004年のRuby on Railsから2020年のHotwireの公開まで、さまざまなアプローチが試されてきました。
Turboは上記の仕組みを15年間継続運用した経験の上に、実際のウェブ開発で必要になるパターンを抽出し、それに絞った構成になっています。
実際にサーバ側でJavaScriptを生成する Server-generated JavaScript Responsesでアプリを作ると、自由度が高すぎることに気づきます。サーバからJavaScriptを送れると、やれることが多すぎてコードが分散してしまいます。一方でほとんどの非同期処理はごく少数のパターンを繰り返していることがわかります。TurboはサーバからJavaScriptを送り込むのをやめ、非同期処理をより簡単に行う方法を提供しています。
<body>タグの中身だけを入れ替えるとページ遷移が速くなります。またキャッシュなども実装しやすくなります。Turboで実現できないような複雑なことを行う場合はブラウザ側でTurboのイベントに応答して、Stimulusなどで処理する方法が推奨されています。またはTurboStreamsを拡張することもできます。
Stimulusはイベント駆動のJavaScriptを書く際の複雑さを解消するものです。Reactはこの複雑さを単方向データフローで解決しました。それに対してHotwireは同じ複雑さをStimulusで解決しています。
インタラクティブなJavaScriptの役割はユーザイベントに応答して、画面更新などの応答をすることです。一見シンプルに見えますが、イベントを発するパーツや更新しなければならないパーツが多くなると、コードがスパゲッティ状になります。また画面のどの要素がどのイベントを発するか、あるいは応答するかが見えにくくなることもあります。
Stimulusは以下の機能を通して、この問題を解決します。
data-*属性により、明示的にDOM要素と接続されます。 HTMLの属性を見るだけで、どのイベントに応答してStimulus Controllerのどのメソッドが呼び出され、どのHTML要素が変更されるかがわかります。インタラクティブなウェブサイトを15年構築してきた経験を土台に、HTML/CSS/JavaScriptを拡張したものがHotwireです。余計なことをせず、過去にやりすぎた部分を削ぎ落としつつ、一貫して使いやすさ・分かりやすさに注力してきたフレームワークです。
ブラウザのネイティブな機能も大幅に進歩していますので、複雑なUI/UXを作る場合でもこれだけの拡張で十分です。