9月6日、「Rails 7は、2021年以降のJavaScriptに対する3つの素晴らしい答えを出すだろう」が公開された。
この記事はDHHによる、Rails 7とJavaScriptに関する投稿である。
Rails 7 will have three great answers to JavaScript in 2021+
Railsは当初からフルスタックである。
私たちは、現代のウェブ開発で生じる主要なインフラの問題すべてに対して、これまで以上にデフォルトの答えを提供することを目指してきた。
データベースとのやりとり、メールの送受信、web socketの接続、HTMLのレンダリング、JavaScriptとの連携など、さまざまな機能がある。
このようなフルスタック戦略はRailsの成功の鍵となっているが、同時に永遠の論争の種ともなっている。
何を入れすぎているのか?何が足りないのか?
この永遠の疑問に一貫して答えるために、私たちは「Rails Doctrine」、特に「The Menu Is Omakase」の3番目の柱に注目している。
だからこそ、デフォルトに頭を悩ませている。その一方で、代替案を出すという選択肢が非常に重要でもある。
ここ数年、JavaScriptの問題ほど、デフォルトに頭を悩ませたり、代替品を精査したりすることはなかった。
特に最近では、絶え間ない変化と根本的な変更により、新しい選択肢が脚光を浴びるようになっている。
しかし、実験を重ねた結果、Rails 7では確かな答えが得られたと思っている。
Rails 7はimport-mapped Hotwireがデフォルトになる
Rails 7では、Webpacker、Turbolinks、UJSをimport mapsに置き換え、さらにHotwireのTurboとStimulusをデフォルトにしている。
これまでにリリースした中で、最も包括的な答えである。
Turbolinks + UJSは、SPAのようなキレのあるアプリを作るための良いベースラインを提供していたが、それ以上にダイナミックなことをする必要があると、ほとんどがBring Your Own JS-FUになってしまう。
Hotwireは、より野心的だ。
TurboはTurbolinksの基本的な機能に加えて、フォーム送信、フレーム、ストリームなどの機能を備えている。
今では、動的要素の大部分をTurboだけで作ることができるようになった(カスタムJavaScriptを書かずに)。
さらに、すでにあるHTML(Railsのサーバーサイドビューから生成)のための控えめなJavaScriptフレームワークであるStimulusもある。
これは、バックエンドにJSONを送信する重いJavaScriptクライアントサイドアプリケーションの完全な代替品である。
このHotwireの設定は、HTTP2、ES6/ESM、およびRails 7のimport mapsを介して提供される。
この三拍子が現代のWebにとってゲームチェンジャーである理由については、すでに詳しく説明したので、ここでその議論を繰り返すことはない。
ここでは、これらの技術とHotwireやJavaScriptのCDNベースのパッケージ管理の組み合わせが本物であるということを繰り返し強調するだけである。
「Alpha preview: Modern JavaScript in Rails 7 without Webpack - YouTube」では、これらがどのように機能するかを紹介した。
数週間前からこのスタックでHEYのバージョンを実行しているが、非常に快適である (完全なレポートとロールアウトは近日公開予定)。
ビルドのための個別の監視プロセスは必要なく、設定と格闘する必要もなく、すぐにリロードされ、nodeツールはまったく必要なく、全体的なパフォーマンスや機能の低下もない。
これはBasecampの私たちにとって、最高の世界だ。
「私たちにとって」というのは、HEYは明らかにこのビジョンを念頭に置いて開発されたからである。
何千ものJavaScriptファイルが詰め込まれていたわけではない(ブラウザベースのESMバージョンでは約130個のJavaScriptファイルを送っている)。
また、JSXのようなトランスパイラを必要とするコードも使用していない。
Hotwireがリリースに向けて磨かれた場所でもあった。
だから、ここで素晴らしい働きをするのは、ある意味当然のことだと思う。
しかし同時に、HEYは決して異常ではない。
実際、最新のWebアプリケーションとしてHEYに求められるレベルはすぐそこにある。
これは、Gmailと真っ向から競合するアプリケーションである。
Gmailは、長い間、分厚いクライアントサイドのフレームワーク、JSONの利用、およびすべての最新のトランスパイラのトリックを使ったアプリケーションとして支持されてきた。
しかし、Gmailは受信箱を表示するために、約3メガバイト相当のJavaScriptをダウンロードする。
HEYは60キロバイト以下のダウンロードだ。
このスタックを使ってGmailのライバルを作り、それが何万人もの有料顧客に広く称賛されるのであれば、おそらくこのスタックを使ってあらゆるものを作ることができるだろう。
つまり、Railsのデフォルトのスタックとして最適である。
Rails 7は従来のJSバンドルを完全にサポートしている
しかし、Railsのもう1つの柱は、大きなテントを広げようとしていることだ。
Hotwireとimport mapsは、すべての人にとっての答えではないことを強調しておく。
素晴らしい答えである。デフォルトの答えでもある。しかし、唯一の答えではない。
Railsは、従来(クライアントサイドのルーティング、重いステート管理、その他の複雑なスタイルを完備)のSPAを開発するための素晴らしいフレームワークである必要がある。
そして、それは実現するだろう。
そこでRails 7では、node/npm/bundlingの設定全体を扱うことを避けるための優れたデフォルトの方法を提供すると同時に、これらすべてを包含する完全にサポートされた代替ルートを提供している。
しかし、私たちはそれを以前とは異なる方法で行うつもりだ。
Webpackerは約5年前に、JavaScriptのエキスパートになることに必ずしも興味のないRails開発者にとって、JavaScriptバンドルパイプラインを使いやすくする使命を持って誕生した。
当時、ブラウザで広く使われるためにはES6にトランスパイルが必要であり、node用パッケージのエコシステムにアクセスするためにはnpmが必要だったため、それを回避する方法がなかった。
私たちはこの現実を受け入れるか、RailsをそのようなアプリケーションのためのAPIに過ぎないものにするかのどちらかだった。
私たちは受け入れることを選んだ。
しかし今日では、Webpackerのトレードオフはあまり意味をなさなくなってきている。
Webpackerは、2つの明確な道の間の泥沼にはまっているようなものだ。
バンドルパイプラインを完全に排除するという新しい道がある。これはセットアップが非常に簡単で、依存関係も少なく、RubyとJavaScriptの間での厄介な分業もない。
そして、JavaScriptの複雑さを隠したり、ラップしたりしないall-inの道がある。
生成されたJavaScriptをRailsアプリケーションで使用するためのブリッジを提供するだけで、すべての答えはJavaScriptのエコシステムに委ねられている。
私はWebpackerの初期バージョンを書いたが、BasecampとHEYの両方で効果的に利用した。
しかし、5年前に行われたトレードオフが現在や将来に役立つとは思えない。
その代わりに、Rails 7は、JavaScriptの世界から見てはるかにスリムで、はるかに伝統的な代替の道を提供することになるだろう。
JavaScriptを開発するには、ソースをapp/javascriptに置き、package.json定義でビルドスクリプトを実行する。
そして最終的なビルドを app/assets/buildsのアセットパイプラインに渡し、ダイジェストスタンプをつけ、CDNの前準備、アプリでの提供を可能にする。
これはjsbundling-rails gemが採用している方法である。
このgemは、esbuild、rollup.js、Webpackに必要な基本的な設定を提供する。
選択したバンドラーの基本的の依存関係をインストールし、必要に応じて設定ファイルを作成する。
そしてデフォルトのエントリーポイントをapp/javascript/application.jsにして、ビルドをapp/assets/buildsに置くという2つの慣習に従っている。
これで終わりだ。依存関係を管理と更新の責任は、開発者にある。
React with JSXや他のJavaScriptフレームワークのように、トランスパイルのステップを必要とするものに全面的に取り組む場合は、おそらくこのパスを選ぶべきだろう。
import mapsを使ってReactで作ることもできるが、それはhtmを介したものになり、全面的に取り組む人にとっては妥協しすぎかもしれない。
もしあなたが今Webpackerを使っているのであれば、jsbundling-rails gemで提供されているバンドラーの一つに乗り換えるのはとても簡単なことだ。Webpackにこだわる必要もない。
基本的にはどれも同じように機能する。エントリーポイントを取得して、ビルドを生成する。
Basecamp 3では当初、Webpackerからesbuildに変えてその道を歩んできた。
しかし、HEYでは全面的にimport mapsを採用した。
どちらの選択も、多くの努力は必要なかった。JavaScriptはJavaScriptのまま。いくつかのインポートパスを調整するだけだ。
もしあなたがまだ強い好みを持っていないが、バンドラーが必要であることを知っているならば、私はesbuildから始めることを勧める。
esbuildは非常に高速で、JSXやTypeScriptにも対応している。
Rails 7では、JavaScriptに3つの明確な選択肢が用意されている
最後に、Railsを単にAPIとして使用するという選択肢もある。
それを利用するSPAは、まったく別のプロジェクトとリポジトリに置いておく。
Railsは長い間、--apiでこの道をサポートしてきて、これからもそうしていく。
小中規模のチームにはお勧めできない方法だが、フロントエンドとバックエンドの間に高い壁を設けてSPAを作ることに専念している大規模な組織の中にいる場合は、意味のある方法かもしれない。
というわけで、Rails 7以降のJavaScriptの話をした。
Hotwireとimport mapsを使ったデフォルトの道。
人気のあるJavaScriptバンドラーの1つとの薄い統合を使った代替の道。
そして最後にフロントエンド用の別のリポジトリを使った厳格なAPIの道。
2021年の現代のウェブ開発の現実に対する3つの確かな答えだ。
まもなくRails 7のアルファ版がリリースされるが、年末までには最終リリースを迎えたいと考えている。
これらのリリースのテストと改善に協力してほしい。