世界を動かす技術を、日本語で。

Railsの使い方が間違っています

概要

  • Rails 8での Vite導入 によるモダンな開発環境の紹介
  • ReactTypeScript などの最新フロントエンド技術との統合
  • 開発効率化のための 多数のツール 導入の流れ
  • シンプルなRails構成との 比較と皮肉
  • 最終的な結論としての Vanilla Rails の魅力

ViteとRails 8のモダン開発環境

  • Vite はRails 8向けの超高速ビルドツール
  • Nodenpm のインストールが前提
  • 最新のフロントエンド技術との連携が容易
    • React 導入でリアクティブなUI開発
    • React Refresh でコンポーネントの即時リロード
  • TypeScript 対応には追加設定が必要
  • Babel.babelrc の設定が必須
  • vite-plugin-ruby でRailsとの連携
  • スタイル管理に PostCSSTailwind CSS を推奨
  • コード品質維持のため ESLintPrettier 導入
  • Husky でpre-commitフックを追加

サーバーサイドレンダリング・リアクティブ機能の追加

  • サーバーサイドレンダリングには Next.jsRemix を利用
  • StimulusReflexHotwire でJSフレームワーク不要のリアクティブ機能
    • ActionCable の設定
    • Redis によるpub/subレイヤー
  • DockerDocker Compose で依存関係を隔離
  • Fly.io でのデプロイや GitHub Actions によるCI/CDパイプライン構築

モダン開発環境の複雑さとVanilla Railsの対比

  • モダンな開発環境は 多層的なツールチェーン と設定作業
    • 例:Vite, React, Babel, PostCSS, Tailwind, ESLint, Prettier, Husky, Docker, Redis, etc.
  • Vanilla Rails はコマンド一発で即起動
  • フォームもナビゲーションも 高速・シンプル
  • 複雑な構成 を皮肉りつつ、 Rails本来の強み を再評価

結論:Just F#$%^& use Rails

  • モダン技術の導入は便利だが シンプルさも重要
  • Rails単体 で十分な開発体験とパフォーマンス
  • 余計な複雑化 を避け、必要に応じて技術選定する姿勢

Hackerたちの意見

「ウェブ開発のツール疲れ」ってほんとに実感するよね。

10年以上前からそうだったよ。趣味を仕事に持ち込むのは、ほんとに愚かで自己中心的だよね。フロントエンド開発者が気分が良くなるなら、「DevOps」の世界もあんまり良くないよ。

プロとしてやってるなら、設定は一度やれば終わりだからそんなに悪くないよ。でも、ワンオフのプロジェクトやウェブ開発がメインじゃないなら、確かに面倒だよね。とはいえ、避けることもできるよ。俺はFresh(https://fresh.deno.dev/)を使ってウェブサイトを作ったけど、それだけで十分だった。いつものNode/Webpackの混乱に比べて、信じられないくらいシンプルだし。しかも、TypeScriptで書けて、TSXも使える。もし複数人でプロジェクトを進めるならESLintを設定するかもしれないけど、他に何もなくても始められるよ。

無料でRailsから得られる便利さが恋しいな。JSの世界と比べると、ほんとに桁違いだよ。多くのJS開発者は、自分たちがどれだけのものを逃しているか全然わかってないと思う。でも、結局、車輪を再発明するのがJSの生き方なんだよね。

JSのオープンさで新しいプラットフォームを作れる力には感謝してる。みんなが車輪を再発明するチャンスがあるのは素晴らしいことだよね。これらのプラットフォームは、同時にいくつか使っても大体うまく動くし、すごく拡張性があってハッカブルだし、全部をローカルでホストできるから、サイト全体が常に変わらない形で作れるって最高!でも、その力にはある程度の自制が必要だよね。できるからって、退屈な開発者や、別のやり方をしてた会社から来たばかりの人が、理由もなく新しいフレームワークを追加するのを防ぐのはチームの責任だよ。

JSで全てを書き直す目的は機能性じゃなくて、ポータビリティなんだよね。

バニラRailsを使ってサーバー生成のフォームやPOSTリクエストで次のフォームに進む時代を覚えてるよ。...10年前でも、かなり古臭く感じた。Railsはウェブアプリ用のフレームワークサポートツールを成長させたのかな?それが話してる便利さなの? > 結局、車輪を再発明するのがJSの生き方なんだよね。これには一理あるよ。根本的な考えは「サーバーサイドとクライアントサイドでどれだけ計算するか」ってことだし、ブラウザがすべての言語を実行できるわけじゃないから、クライアントサイドの動作に最短で到達するのはJSなんだよね。だから、その意味では車輪の再発明が多いんだ。(一度コードを書いて、どちらの環境でも動かすという考え方は、波があるのを見てるよ。boardgame.ioは、ターン制の状態を持つゲームを書くためのJavaScriptフレームワークで、特定の著作権パターンを使って、サーバーとクライアントの両方でコアの動作ライブラリを実行するから、クライアントはサーバーがルールを処理してゲームの状態を更新する間に、何が起こるかを予測できるんだ。)

Ember.jsはRailsコミュニティの大物たちによって作られたんだけど、Railsのようにバッテリーが含まれたオールインワンフレームワークって大きな約束をしてたんだ。でも、他のフレームワークほど人気が出なかった理由があるよね。

たしかに、便利さはあるけど、長期的にはコードベースを更新し続けないといけないし、Railsのトレンドに追いつかなきゃいけないよね。

JSにはRailsに似たフルスタックフレームワークがいくつかあるよ。Sailsっていうフレームワークもあるし… JSで解決する問題はRailsで解決する問題とは違うから、フレームワークの見た目も違うんだ。

今の状況は昔より悪化してるけど、概念自体は新しくないよね。15年前にDjangoを学んでた時、髪の毛を引き抜きたくなるほどだったのを覚えてる。チュートリアルでは、特定のバージョンのVagrant、VirtualBox、Chefをインストールするように言われたけど、どれも壊れてたりインストールが面倒だったりした!今でもDjangoは使ってるし大好きだけど、そんなことは気にしないよ。Django Rest Frameworkもまた別の気を散らす要素だった。

スティミュラスとホットワイヤーが今の「Rails流」だね。ドキュメントを読んだけど、まだ全然わからないよ。自分のJavaScriptコンポーネントを何度も再発明してる感じがする。個人的には、Rails 8 + Inertia.js + Reactは、特にshadcnコンポーネントを使うと、ずっと「車輪を再発明」してないと思うよ。

個人的にはRails 8 + Tailwind + Stimulusが好きだな。Nodeは使ってないよ。

Railsの大ファンだけど、StimulusとHotwireの現状には悲しくなる。コンセプトは素晴らしいし、実行も良いかもしれないと思う。でも、ドキュメントが信じられないくらいひどくて、始めるのも一苦労。どのプロジェクトで使うかによって、最終的に行き詰まるかどうかを判断するために必要なことを学ぶのが難しいんだ。

これ。HotwireのフロントエンドをInertiaに置き換えたら、全然違う。100%一人で作業する場合(しかも小規模なプロジェクト)じゃない限り、Hotwireは本当に誰も作業できないぐちゃぐちゃな状態を生むよ。今まで見た中で最悪だわ。

これ、ほんとにそうだよね。俺はturboやstimulus、hotwireを使ったことがあるけど、ブラウザやウェブページとのやり取りにはステートレスな方が向いてるんだよね。問題は、求められるユーザー体験やユースケースが全部ステートレスじゃないってこと。hotwireのエコシステムは、他の人気のあるJSフレームワークに比べてほんとに小さいし。もし在庫を探してるなら完璧だけど、最近触った入力に基づいて何かを更新したいなら、もっと複雑になっちゃうし、正直言ってそれだけの価値はないと思う。ソロのRails開発者なら、好きなものを使えばいいけど、Reactのエコシステムや他の人気のあるJSエコシステム(Vueとか)はすごく強力で、選択肢がたくさんあるよ。StimulusはjQueryから2歩後退してるし、イベントデリゲーションパターンを逆転させちゃった。Railsコミュニティ以外では誰も使ってないよ。

小さなインタラクションにはSymfonyと一緒にStimulusを使ってて、結構気に入ってるよ。小さくてデザインもいいAPIだと思う。ただ、Turbo/Hotwireの全体は試してないけど。複雑なページや状態が必要な時は、普通はVueを使うかな。

2007年からRailsのコードを書いてるけど、時間が経つにつれてスタックが複雑になった理由があるんだ。ほとんどのチームはこの定義で正しくやったことがないと思う。おまかせフレームワークの問題は、最初の選択肢に同意するだけじゃなくて、その後のすべての選択にも同意しなきゃいけないことなんだよね。しかも、開発チーム全体をその旅に引きずり込む必要がある。すごくパワフルなフレームワークだけど、メンテナは一般的に善意のある人たちで、クリスタルボールを持ってるわけじゃないから、後で捨てられた選択肢も多い。だから、今のところ、野良で見かけるバニラRailsアプリはほとんどない気がするよ。(Docker以前にRailsアプリをデプロイするのがどうだったか覚えてる年齢だしね。rsyncで同期したり、タールボールをインスタンスの群れに落としたりして、必要なファイルをtouchしてアプリサーバーをリセットさせてた。Dockerとk8sは多くの苦痛をもたらすけど、それよりはマシだよ。)

Docker以前にRailsアプリをデプロイするのがどうだったか覚えてる。rsyncで同期したり、タールボールをインスタンスの群れに落としたりして、必要なファイルをtouchしてアプリサーバーをリセットさせてた。これを覚えてるなら、かなり壊れたセットアップを思い出してるね。古いCapistranoのデプロイシステムでもそれよりはマシだよ。

rsyncで同期したり、タールボールをインスタンスの群れに落としたり もう少し詳しく教えてもらえる?大したことないように聞こえるけど。

だから、俺はSinatraにいつも特別な思い入れがあるんだ。

30人以上の開発者が同時に必要ないプロジェクトには、フロントエンドとバックエンドの分離がもたらす複雑さは不要だってことを、フリーランスとして1〜2人のプロジェクトをオーバーアーキテクトすることで痛感したよ。最近は、DjangoにちょっとTailwindを乗せるだけで済んでる。

これに同意する。ほとんどの業界では、クライアントはソフトウェアが超スケーラブルなマイクロサービスに分かれているか、モノリス + PostgreSQLに依存しているかなんて気にしないよ。

今年の初めにDjangoの開発者を採用しようとしたんだけど、ケーススタディではほとんど全員がDjangoで薄いAPIバックエンドを作って、フロントエンドにはReactの巨大なものを使ってた(ビジネスロジックのほとんども)。動機を聞いても、ほとんど誰も説明できなかった。SSRを使ってた数少ない人の一人を採用したよ。

もしすごくインタラクティブなフロントエンドを作ってるなら、どうする?

これがRailsの根本的な弱点だよ。UIがそのままじゃ使えないから、「Railsをやる」だけじゃダメなんだ。10年前のBootstrapでも、今のReactでも、何かを追加しなきゃいけなかった。常に付け足しで、ずっと変わり続けてる。

実際に「Xをやる」だけのフレームワークってどれ? 良いフレームワークは他の技術と簡単に拡張できるべきだよね。

これがすべてのサーバー・ブラウザアーキテクチャの弱点でもあり、強みでもある。世界(またはApple)は、統一されたフロントとバックエンド(Flash/Flexみたいな)は最適じゃないって決めたんだ。

これが本当だとはあまり思わないな。FigmaをRailsで作るのはあまり望ましくないかもしれないけど、平均的なSaaSのCRUDアプリにはRailsがぴったりだし、ちょっとTurbo Framesを加えるだけでいい感じになる。Reactが必要かどうかを判断するための知識が不足してることが多いんだよね。

この話題は10年以上も書き直されてる。いわゆる「複雑さ」っていうのは、特定の問題を解決するためのツールのリストに過ぎない。ツール自体が問題じゃなくて、現代のウェブ開発には複雑さが内在してるんだ。他のフレームワーク、例えばASP.NETやGUIデスクトップフレームワークでも似たような「隠れた」複雑さが見られるよ。RailsをAPIバックエンドとして使って、フロントエンドをReactで処理するなら、従来のRailsモノリスとはほぼ完全に異なるアプリケーションアーキテクチャになる。だから、ツールのリスト(Vite、React、Prettierなど)は、ほぼ別の問題に対するものだよ(Railsをフロントエンドに使う場合を除いてね;Railsをフロントエンドに使いたいなら、ちゃんとRailsを使えばいいのに、ミックスするのは全然好きじゃない)。本当の問題は学習方法論だと思う。今の多くの開発者は、ウェブの基本を学ぶ前にフレームワーク(ポイント4)からキャリアをスタートさせてる。マークアップにはHTML、スタイリングにはCSS、サーバーサイドロジック(例えば、POSTできて同じURLで全く違うページを返せる)や動的コンテンツのためのデータベースを学ぶ。そして、インタラクティブ性のためにJavaScript。ツールを受け入れよう:リストにある各ツール(Vite、Tailwindなど)は理由があって存在していて、現代のウェブアプリケーションには全部必要なんだ。「多すぎる」って言うのは、エコシステムの現実を理解してないアマチュアの意見だね。

記事のポイントは、そもそも「モダンなウェブアプリケーション」を必要としてなかった可能性が高いってことだと思う。バニラRailsで十分動くから。でも、バニラRailsでの選択を理解しない限り、それに気づくことはないよね。

複雑さはウェブ開発に内在するものじゃないよ。むしろ、今は少ないものでより多くのことを成し遂げることができるようになった。HotwireはちょっとバニラRailsみたいなもので、ウェブソケットを通じてコンテンツがライブで更新される、すごくモダンな体験を作れるんだ。設定も基本的にワンライナーで済むしね。RailsでのJS配信のデファクトスタンダードも、インポートマップのおかげでずっとシンプルになった。ビルドステップも必要ないし。Tailwindのサポートも、新しいRailsアプリを生成する時にフラグ一つで簡単にできる。デプロイもKamalのおかげでさらに簡単になった。だから、複雑さはウェブ開発に内在するものじゃないし、この記事がHotwireを「複雑さ」として扱ってるのは間違いだと思う。むしろ、簡単にしてくれるんだよね。学ぶことについての君の意見には賛成だけど、学ぶことはもっと技術を学ぶことじゃなくて、少ないものでより多くのことを成し遂げる方法を学ぶべきだと思う。誰でも20種類のプログラミング言語やサーバーを使えるけど、4つを使って同じことを成し遂げて、3人の開発者で千人のチームを上回るのがスキルだよ。

反論:これらのツールは複雑さを加えるだけで、必要ないよ。システムの外に出て中を見れば、狂気が見える。彼らが解決する問題は他のツールによって作られたもので、問題を生み出すシステムなんだ。

複雑さは現代のウェブ開発に内在するものだ いや、そうじゃない。 > 彼らは現代のウェブアプリケーションには必要だ いや、必要じゃない。 > 「多すぎる」と言うのは素人の意見だ わお。

そして、これらはすべて現代のウェブアプリケーションには必要不可欠だ。現代ってあんまり意味がないけどね。

これ可愛いけど、Railsアプリケーションのライフサイクルの中で、bundlerからwebpacker、sporkets、Propshaft、importmaps、jsbundlingに移行する回数については触れてないよね。autoloaderからzeitwerk、TurboからHotwire、他に何があるか神のみぞ知る。Railsのニュースレターの広告を見てみて、どれだけのものがRailsアプリをアップグレードするためのプロフェッショナルサービスか確認してみて。

(ジョンが一つのコマンドを実行する。アプリが瞬時に起動し、動作するフォーム、瞬時の読み込み時間、超速のナビゲーション。)そうだね。Viteを使ってないなら、どうやってバンドルしてるの?あ、バンドルしてないの?ってことは、TypeScriptも使ってないのかな?面白いね、エラーはどうやってキャッチするの?あ、プロダクションでクラッシュさせっぱなし?他のエンジニアは君のコードの意図をどう理解するの?あ、理解できないんだ、なるほど。Reactを使ってないなら、何を使ってるの?バニラJS?「Reactはいらない、ただの複雑なゴミだ、自分で作る」と言った人が、結局Reactの半分をバグだらけで遅い実装を作るっていうのは統計的な事実だって考えたことある?あ、Prettierも使ってないの?じゃあ、どうやってコードをフォーマットしてるの?あ、全然フォーマットしてない、ただの大混乱?ESLintも使ってないの?面白いね、チーム内でコードの一貫性をどう保ってるの?それは気にしないんだ?ふーん。この記事に出てくるほとんどの技術は、ちゃんとした理由があって存在してるし、実際の問題を解決してるんだよ。著者が直面した問題じゃないかもしれないけど、著者は解決してる問題を理解してないし、最後の「オチ」は誰でもこの技術を捨てて開発者体験を改善できるみたいなことを示唆してる。「壊す前にルールを学べ」っていうのがここに当てはまる。これは抽象を馬鹿にするだけで、なぜそれが存在するのかを理解しようとしない好奇心のない記事だね。[1]: まあ、確かにいくつかの抽象は面倒なこともあると思う。でも、著者はなぜReactみたいな合理的なものを選んだの?Angularを叩く理由はないの?ちょっとおかしいよね!

記事のポイントは、これらのツールは冗長だってことだと思う。Railsはフルスタックフレームワークだから、ウェブアプリを作るための機能はすでに備わってるし。

問題は、これらの問題が特定のソフトウェアの一部にしか関係ないってこと。多くのソフトウェアは、そんなに堅牢である必要はないし、チームで開発する必要もない。たまにランタイムバグが出ても、何十ものパッケージとの互換性を維持するためのコストには見合うよ。ほとんどのプロジェクトは、非常にシンプルなCRUDアプリだしね。