はじめに
※ この文章はベータ版です。
Yahoo!知恵袋にあった間違いだらけのベストアンサーがあまりにも...だったので書いています。
#このベストアンサーの問題点
著者が、よく知りもしない情報について、きちんと調べもせず、以前、聞き齧ったorどこかで読んだような気がする、うろ覚えの情報をベースに、回答しているようにしか見えません。
自分がうろ覚えの情報で回答することで、ネット上に誤情報をばら撒く可能性を 考えていない時点で、自分はこの著者が技術屋or技術屋を目指す人間なら、アウトと評価します。
この著者、「はず」「と思う」を多用すること
で、うろ覚えの情報で回答していますよアピールをしている気が...うろ覚えの情報で回答していることに、何ら問題を感じていないようにみえます、自分のうろ覚えの情報が間違っていた時の
ための予防線を張っているようにも...。
「はず」「と思う」が多用されていても、
質問者や読者が正しい情報と誤認識する
可能性があります、「はず」「と思う」を
付けたからと誤情報かもしれない、
うろ覚えの情報で書いてもいい、と考える
のは間違いです。
この質問の質問者は、うろ覚えで書かれた誤情報を正しい情報と、誤認識してしまっている気がします。
ネット上で書く以上、うろ覚えの情報で書くのではなく、自分のうろ覚えの情報が正しいか、ネット上で最新情報をキャッチアップし、その情報と照らし合わせて検証してから、正しい情報をベースに書くべきです、エンジニアなら尚更、Qiita etcに投稿する際も同様です。
この質問、2021/01/01 に投稿され、その日の
うちに締め切られていて、間違いだらけのベストアンサーを別の回答で正すこともできない状態になっています。
うがった見方をすれば、質問の投稿者とベストアンサーの著者が同じ人間で、わざと間違った情報をネット上に意図的に晒している、とも受け取れます。
Ruby自体、時代にあわせた変化や進化はもうない(と思います)
Ruby3.0.0で、
型チェック用基盤 の RBS / TypeProfと、並行・並列処理 の Ractor & Fiber Scheduler が入ってますけど...。
Ruby3.1.0では、
YJIT (Shopify で開発されたJITコンパイラ) etc が入ってます。
Ruby3.2.0では、YJIT が実用可能なレベルに達し、実験的機能ではなくなっています。
(もう一つのJITコンパイラである (YARV-)MJIT は実験的機能のままです。現在は、(YARV-)MJIT は実装を見直し、RJITに改称しています。)
Ruby2.6から、JITコンパイラが入り、Ruby3.1で YJIT が導入、JITコンパイラの改良が続けられ、Ruby3.2で YJIT は実用可能なレベルになっています。
3.5では、YJITの改良版ZJITが試験?導入される予定となっています。
時代の要請に合わせた新機能ですよね。
言語仕様ではなく実行環境の新機能ですけど...。
3.2.0では、YJITは、実戦投入可能なレベルには達しているものの、デフォルトでは offになっています。3.3/3.4では、YJITは改良され、パフォーマンスやメモリー消費が大幅に?改善しています。
3.5に試験?導入予定のZJITでは、JITコンパイル済み(ネイティブ)コードが再利用されるようになり、パフォーマンスやメモリ消費が大幅に改善されるようです。
Ruby3.x、他にも新機能あります。
「Ruby 新機能」でググれば、すぐにキャッチアップできる情報...。
Ruby原作者の Matz氏 が発言していた、大きな変更はしない、は、破壊的な構文・ライブラリの変更はしない、という意味合いで発言されたモノで、言語に対する大きな変更を今後しない、ではないです。
Matz氏は、公式に、Rubyを時代にあわせて変化・進化させていくニュアンスの発言をしています。
Rubyは、1.8 → 1.9 → 2.0(2013/02にリリース)、で、かなり大きな痛みを伴う変更が入って、実行環境の実装も、それまでのインタープリタから、バイトコード・インタープリタ、に置き換えられています。
2.xへの移行は、Railsが割と短期間で 2.xに対応 したこともあり、わりと短期間(数年?)で完了したように感じています。
Pythonは 2.x→3.x で、多岐に渡る、かなり大きな?変更が入って、3.0 が2008/12にリリースされましたが、2.7が2020/01に、EOF(End Of Life)になったにもかかわらず、広く利用され続け、3.xへの移行には時間が掛かりました、現在も完全には移行完了していないかもしれません。
例えば、Google Chromeのビルドツールであるgn は 2.7? で書かれていて、3.xに移行するまでに時間が掛かりました。
2021/02時点では、移行の気配はなかったので、それ以降に移行作業が急ピッチで?行われた模様です。
Migrating Chromium to Python3
2021/02/16、GoogleがPSFのビジョナリー・スポンサーになり、CPythonの開発支援及び 基本的な周辺ツール・サービスの改善に乗り出す、ことを発表しました、これにより、Googleの提供するPython製ツールのいくつかで3.xへの移行が進んだ模様。
Perlは 5.x→6.0 で 大きすぎる痛みを伴う変更が計画?されましたが、6.0の開発は何年も停滞して、ある程度、実装が進んだ頃に、結局、Perl6.0→ Raku とリネームされ、別の言語になりました。
言語仕様への大きな変更は、大きな痛みを伴う(ユーザーに大きな痛みを強いる)ので、ユーザーの要望に応える形での変更でもない限り、ユーザーに痛み以上のメリットを提示できないと、移行が進まないようです、ので、仕様の策定者は実施前に熟考に熟考を重ねる、と共にユーザーの声を聞く必要があるようです。
Ruby の仕様に、破壊的な変更が、2.0 以降、入っていないのは、Python・Perlの言語開発者による独善的な?変更での失敗に学んでいるから、だと思います。
「Railsはオワコン」の問題点
上記のベストアンサーのように、聞き齧った、どこかで読んだ気がする、うろ覚えの情報を基に「Railsはオワコン」と書かれたり言われたりしていることが多い気がします。
自分の(身の)周りではこうだったから、自分の知ってる・見えてる範囲内ではこうだから、自分の勉強したor調べた範囲内では、こうだったから、で、自分の偏見や私情も入れて、(最新の情報も含め、広く情報を集め、その情報を精査した上での現状分析etcを行うようなことはせずに、)「Ruby/Railsはオワコン」と著者が書いていることも多いです。
(そんな著者は、自分の知ってる/見聞きした情報を自分の都合のよいように解釈してる場合が多い、感じです。)
Ruby / Rails はオワコンなのか?
Rubyでは、Rails登場以前に、これといったウェブ・アプリケーション・フレームワーク(WAF)がなく、Rails登場 により、はじめて、RubyがWEBアプリ開発の選択肢の一つになりました。
Railsの完成度が初期から割と高く、時代の変化に対応しながらバージョンアップされてきたこともあり、Rails以外のWAFが登場しても、Railsを超える or Railsと並ぶ完成度のモノはなかったので、RailsがRubyのWAFのデファクトであり続けてきました。
デファクトであるRailsによるエコシステムが醸成され、WAFの再発明をしたり、他のWAF用のライブラリを開発するよりも、Rails用のライブラリを開発したほうが、世の中で広く使われる状況になっているので、今もRails用のライブラリが多数、開発・メンテナンスされ続けています。
PHPやPython etcのように同じような完成度のWAFが多数あると、同じ用途用のライブラリがWAF毎に存在し、GitHubでのプロジェクトの数も必然的に多くなります。
Rubyの場合、WAFの開発まわりがほぼRailsに集約されているので、同じ用途のRails用ライブラリが複数あっても、PHPやPython etcに比べてWAF関連のGitHubプロジェクト数は少なくなっています。
なので、Ruby / Rails のGithubでのプロジェクト数が PHP /Python etcと比べて少ないことを「Ruby / Railsはオワコン」の根拠の一つに挙げるのはナンセンスですね。
ちなみに、みんな大好き?GitHubのバックエンドにも、Rails (Ruby)がツカわれています。
Rails は、7.0でJSまわりの刷新 etc、7.1で rails new 時のDockerfileの自動生成機能、複合プライマリキーのサポート、7.2で PWAサポート etcが追加されています。
8.0で、Sprockets → Propshaft、認証機能ジェネレータの追加 etcが行われています。
推敲中...
Ruby のパフォーマンス
2021/01/19、Google Cloud Functions (GCF)でのRubyのサポート開始が発表されています。
AWS Lambda は、2018/11 にRubyのサポートを開始しています。
Amazon も Google もクラウド・サービスを提供している大企業であり、自社のインフラを圧迫するような、自社のサポートする他の言語と較べてパフォーマンス面で明らかに劣る言語を自社のサーバーレス・サービスで正式にサポートすることはありません。
Rubyも、両者が自社のサーバーレス・サービスで正式にサポートする他の言語と同じように、両者が自社のサーバーレス・サービスでサポートする言語の実行環境に求めるパフォーマンスの要件をクリアしているはずです。
Rubyは、2.0.0リリース以降、バージョンアップする度に、互換性を維持しながら、パフォーマンスが改善されてきています。
(Ruby が両社の求める要件をクリアできたのは、Rubyコミッタ陣による地道なパフォーマンス改善の賜物だと思います。)
また、両者が自社のサーバーレス・サービスでの Ruby のサポートを決定するにあたり、Rubyのユーザーベースを調査し、Rubyに、サポートするために掛かる開発費用をペイできるだけでなく、掛かった費用以上の利益を自社にもたらしてくれるだけのユーザーベースがある、ことを確認しているはずです。
Rubyが世界でユーザーベースが縮小している引き潮の言語ではなく、近年、ユーザーベースを拡大してきている言語だからこそ、両社が自社のサーバーレス・サービスでの正式サポートを決定したのだと思います。
(AWS LambdaでサポートされているCOBOLのように、世界的にみて引き潮ではあるものの、エンタープライズ企業(大口顧客)の要望?でサポートされている例外もあるにはあります。
社内のエンジニアにPythonユーザーが多いことで知られ、Pythonの生みの親である グイド・ヴァンロッサム 氏が在籍していたこともあるGoogle が、自社の サーバーレス・サービス GCF でのRubyのサポートを決定したのには、時代の変化を感じます。)
2023/06/14 に、AWS LambdaでRuby 3.2の利用が可能になっています。
Ruby/Railsは遅い?
Rubyは バージョンアップの度に、パフォーマンスが改善されてはいるものの、バイトコード・インタープリタでの実行であり、JIT(コンパイラ)
は導入されているものの成熟しておらず、また、JITの適用されるコードは全てのコードではないので、同じくスクリプト言語である PHPやPython(のJIT有効時)と処理速度面で同等になってきてはいるものの、ネイティブコードの生成されるGO etc や JITの成熟しているJava etcに較べて、Rubyのみで書いたコードが処理速度面で見劣りするのは事実です。
Rubyは、ネイティブ拡張の作成・組み込みが可能であり、標準ではC言語、外部ライブラリによりRust etc をサポートしています。
また、処理速度の必要とされる機能を提供する Gem の多くは、ネイティブ拡張を作成/利用する形で実装されています。
Rubyは、バイトコード・インタープリタまわり・JITの改良etc により、バージョンUP毎にパフォーマンスを向上させてきています。
WEBアプリでは、言語の処理速度よりもデータベースでの処理やネットワークの応答に掛かる時間のほうが大きく、言語自体の処理速度は、WEBアプリのパフォーマンスにおいて、多くの場合、それほど大きな比重を占めていません。
WEBアプリにおいて、言語自体の処理速度がパフォーマンスに大きな影響を与える場面では、非同期で処理するようにするor別の言語で実装して呼び出すようにする etcの複数の選択肢の中から実装方法を選択すればよいのです。
同じ機能を提供しているGemであっても、実装方法や実装ロジックによって処理速度やメモリ効率が変わってくるので、より処理速度の速いGemやより省メモリのGemを利用することでもパフォーマンスを改善できます。
Rubyは様々な機能を提供するGemの存在する生産性の高い言語なので、その高い生産性を享受しつつ、言語自体の処理速度が必要となる場面では他の言語も併用していくのがよいかと思います。
GitHub や Shopify etc がバックエンドの開発にRailsを採用しています(勿論、処理速度が要求される場面では他の言語も併用しています。)
Rails7.2からは、2023/12 リリースのRuby3.3.0以降で動作させている場合、YJITがデフォルトで有効になっています。
Ruby3.1で YJIT が導入、3.5では、YJITの改良版ZJITが試験?導入される予定となっています。
推敲中...
Rails のフロントエンドまわり
Railsのフロントエンドまわりがレガシーにみえることが 「Ruby / Rails オワコン」の根拠の一つになっている気がするので、書いてみます。
rails-ujs & remote: true & .js.erbの組み合わせでAjax化するコードは、昔、書かれたコードを、メンテナンスしている人、でもない限り、Railsのプロジェクトで見掛けることは、(ほとんど)なくなっています。
Railsに含まれている機能のみ?で、フロントエンドを構築するのは、最早、最適解ではなく、レガシーなスタイルです。
Rails6では、Webpacker (Webpack)経由で、Vue.js、React、etcのクライアントサイドJSフレームワークと組み合わせて、フロントエンドを構築することが主流になっていました。
Rails7からは、importmap-rails or jsbundling-rails(Webpack/esbuild/Rollup)経由で、Vue.js、React、Stimulus etcのクライアントサイドJSフレームワークと組み合わせて、フロントエンドを構築することが主流になっています。
(モジュールバンドラーを利用したい場合には、jsbundling-rails、Import maps で事足りる(モジュールバンドラー不要の)場合には、
importmap-rails )
Webpacker -> JavaScript Bundling for Rails (jsbundling-rails)
モジュールバンドラーの1つであるWebpack の登場及び普及に伴い、Rails本体に、Webpackのラッパーである Webpackerが導入されました。
Webpackerは、Webpackに詳しいフロントエンド・エンジニアをユーザーとして想定したモノ、ではなく、フロントエンドを知らないRailsエンジニアをユーザーとして想定したモノで、Webpackを知らなくても、設定を触らなくても、手軽に利用できる、ことが売り?でした。
Webpackerの、Webpackのラッピング(抽象化)が、Webpackにあるカスタマイズの自由度の多くを台無しに近くしていて、WebpackerにWebpackほどのカスタマイズの自由度はありません。
Webpacker経由でのWebpackのカスタマイズは、Webpackerの仕組みを理解していないと、ドキュメントに書かれているモノ以外、行えません。
そして、Webpackerのドキュメントにカスタマイズについての記述が足りませんでした。
Webpackerの開発者に、Webpacker経由でのWebpackのカスタマイズを自由にさせる気はなかった、ように思えます。
Webpacker5.0.0のリリースにあわせるように、Webpackerのドキュメントにカスタマイズについての記述が追加されました。(まだ足りない感じです。)
Webpackerは、手軽に使えることが売り、なので、仕方がない面はあります。
Rails6で、Webpackに詳しいフロントエンド・エンジニアの方がいるRailsの開発環境で、Webpackをフル・カスタマイズしたい要望がある場合に、元クックパッド社の方が個人で開発して公開している、Webpackの薄いラッパー、Simpacker、を以前はおススメしていましたが、今はRails7用に開発された jsbundling-rails を オススメします。
Simpackerを採用していたRailsでの開発プロジェクト(の大半)は、jsbundling-railsに移行済みか、と思います。
Rails6(→Rails7)での、Webpacker から jsbundling-railsへのリプレース、(割と)低コストで行える、と思います。
Webpackerで事足りている場合、リプレースする必要はないです。
Rails6→7 への移行を見据えている場合、
jsbundling-railsへの移行(してからのRails7 移行)をオススメします。
Rails7では、複数のモジュールバンドラー(esbuild/Rollup/Webpack)に対応した、薄いラッパー、jsbundling-rails が導入され、Webpackerは Rails本体からパージされました。
Webpackerでは、Webpackの設定ファイルを、直接、書き換えられず、Webpackerの流儀に則る必要があり、また、Webpackは設計上の問題によりパフォーマンスがよいとはいえないので、Webpacker -> jsbundling-rails はよい選択だったと思います。
Webpacker は、名称が Shakapacker に変更され、有志による開発・メンテナンスが行われています。
Rails7では、jsbundling-rails / importmap-rails の選択が可能です。
jsbundlings-rails は モジュールバンドラを利用してサーバーサイドでjs の依存性管理/依存性解決/バンドルを行います、
importmap-rails は Import Maps (仕様)を利用してクライアントサイド(ブラウザ)でjsの依存性管理を行います。
importmap-railsは、Rails7.0でデフォルト扱いになってはいるものの、クライアントサイドでJSの依存性管理を行うため、依存性解決の手段がなく、また、JSのバンドルを行わず、JSライブラリもそれぞれダウンロードされるので、パフォーマンス上の懸念もあり、当分、デファクトにはならないと思われます。
また、Rails7 では、CSS管理の仕組みとして、cssbundling-rails も導入されています。
cssbundling-rails は (JS)モジュールバンドラを利用してサーバーサイドでcss の依存性管理/(依存性解決/)バンドルを行います。
Webpacker が Sprockets を置換可能であるのに対し、jsbundling-rails or importmap-rails(+ cssbundling-rails)は Sprockets / Propshaft との併用を前提にしています。
jsbundling-railsもcssbundling-rails も(Sprockets / Propshaft 経由でRailsサーバが扱えるように)Rails のapp/assets下にバンドルしたファイルを配置します。
jsbundling-rails/cssbundling-rails は2024/02現在、
リリース済みの1.3.0/1.4.0 以降では、JSパッケージマネージャとして Yarn or Bun に加え、NPM / pnpm をサポートしています。
Sprockets -> Propshaft
Sprocketsは、Rails3? で導入された、クライアントJSやCSSのライブラリ(アセット)を管理する仕組み です。
Webpacker登場前夜には、設定を追加することで、node_modules ディレクトリ下にある JSライブラリやCSSを参照できるように変更された、Sprockets4の開発途上バージョンが、GitHubのリポジトリに存在していました。
Webpackerが登場し、Rails5.1にWebpacker が含まれることになった後、一時、開発が停滞していたものの、その後、開発が再開し、Sprocket4 がリリースされ、Railsに含まれて
います。
Webpacker・Sprockets4 登場前のように、JS/CSS(のライブラリ) をラッピングした gem を用いて、Railsオンリーで JS / CSS を管理するのは、既に、レガシー・スタイル になっています。
JS(ライブラリ) / CSS(ライブラリ)をラッピングした gem のほとんどは更新を終了しています。
開発を継続している ラッパーgem は、対応するNPMパッケージの導入をサポートする形に実装が変更されています。
tailwindcss-railsは、importmap-railsと併用する(モジュールバンドラを利用しない)場合、NPMパッケージを利用せず(スタンドアロン版のTailwind CLIを利用しています)、モジュールバンドラを利用する場合、NPMパッケージを利用します。
Rails6では、Webpackerオンリー
or Webpacker + Sprockets4
で、JS/CSS のライブラリを管理する、形が主流になっています。
Rails6では、Webpacker + Sprockets4
では、node_modules下は NPM etc で管理し、Sprockets4には node_modules下を参照させるのみです。
Rails7 (Hotwire) でも、JS / CSS の管理は、Yarn or NPM etcで行うのが主流になっています。
Hotwire関連のgemは、JS / CSS を NPMパッケージ にしていて、管理を NPM etcまかせ にしています。
Rails7 では、前述のとおり、Webpacker がパージされ、代わりに、importmaps-rails or jsbundling-rails(+ cssbundling-rails)を選択する形になりました。
Propshaft は、Sprocketsに含まれている機能の多くがモジュールバンドラ(webpack/esbuild/Rollup)での代替、及び、HTTP2仕様を実装したWEBサーバ(Apache/Nginx etc)の普及により不要になったため、Sprocketsから不要となった機能をはずし軽量化したSprockets後継のアセット管理用の仕組みとしてRails7に導入されました。
Propshaftは、Sprockets 同様、importmap-rails or jsbundling-rails (+ cssbundling-rails)と併用できます。
Propshaftには、最低限の機能しかない、ので、Propshaft(のみ)で事足りる場合にはPropshaft(のみ)、事足りない場合には、モジュールバンドラー(webpack/esbuild/Rollup)と併用する形になるはずです。
Propshaft は、Sprockets互換ではないので、注意が必要です。
Propshaftは、ドキュメントの整備(Sprocketsとの挙動の違いの説明etc)が十分ではないです。
Propshaft は、0.6.4以降から、node_modules下(に導入された外部ライブラリ(css/js))を扱えますが、Propshaftで直接扱うと、パフォーマンスの低下に繋がるので、node_modules下は、基本、モジュールバンドラー or DartSassetc のツール経由で扱い、Propshaftで直接扱うことはしないほうがよいです。
Propshaft は Rails8.0 で デフォルトとなり、Sprockets はフェードアウトしました。
推敲中...
CoffeeScript -> JavaScript or TypeScript
Rubyライクな構文をもつAltJSであるCoffeeScript は、Rails3.1でJQueryと一緒に Rails に正式採用されました。
当初は、Railsプロジェクトでデファクトの(ような)扱いとなり、広く利用されていましたが、JavaScriptへの変換が独特で、意図せぬ挙動に悩まされるエンジニアが多く、次第に利用されることがなくなっていき、ブラウザ間でのJavasScriptの互換性の向上、Babel の登場 及び 成熟& Webpackの登場 もあり、Webpacker登場前夜の頃には、既に、Railsプロジェクトのほとんどで採用されなくなって
いました。
Rails6.0で廃止されましたが、レガシーがついに廃止されたか、な感じでした。
型チェックがほしい場合、TypeScriptが、特にいらない場合は、JavaScriptが、Railsプロジェクトでも、採用されています。
推敲中...
Turbolinks -> Turbo
Turbolinks、2019/02 に、Coffee Script -> TypeScriptしてます。
Turbolinksの後継である Turbo は最初から、TypeScriptでの実装になっていました。
が、Turboは、コードの規模が然程大きくはなく、その性質上、実装(内部)のコードが型安全であることは然程重要ではないので、TypeScriptを採用するメリット(型安全)よりもデメリット(型安全にするために、コンパイラ(型チェッカー)を通すための記述を要求され、その記述(ときには型パズルが要求される)に時間を取られる)のほうが大きいとの判断がなされ、2023/09/06に TypeScript ->JavaScript のPRが出されマージされています。
Turbo8以降、Turbo を TypeScriptファイル(.ts)で厳密に使うには、型定義ファイル(.d.ts)が別途必要になります。
Hotwireにおいて、Turbo は黒子に近く、TypeScript or Javascript でユーザーがコードを書く時にTurboのコードにアクセスすることは、(ほとんどの場合、)Turbo.start()以外、ありません。(Hotwireについては後述します。)
jQuery -> Pure JS (JavaScript) etc
jQueryは、Rails3.1で、Coffee Scriptと一緒に正式採用されました。
Coffee Scriptが、RubyライクなAltJS、だから採用されたのに対し、jQueryは、採用当時、フロントエンドまわりで、DOM操作 の煩雑さを隠蔽しつつ、ブラウザ毎のイベントetcの挙動の違いを吸収してくれるライブラリとして、デファクトの地位をほぼ築いていて、多数のUIライブラリがjQueryプラグインとして多数存在していたことから、採用されました。
その後、HTML仕様のアップデート&メンテナンスのできないW3C に業を煮やした(見限った?)?ブラウザベンダが中心となって結成し、後にHTML5となる仕様の策定を開始していたWHATWGが、策定中の仕様をHTML5仕様のベースにすることを W3C に同意させ、HTML5仕様 の 策定の主導権 を W3C から奪うとともに、HTML関連仕様の策定の主導権も W3C から奪います。
(ニュアンスは間違っていないはず。)
ブラウザの開発者が多数、HTML5仕様とHTML関連仕様の策定に関わるようになり、HTML関連の新仕様は、含まれる新機能が主要ブラウザに実装され、動作検証されるまで、勧告が行われない体制に変更されました。
また、ブラウザの挙動が、HTML仕様及びHTML関連仕様である程度、規定されるようになり、この体制変更後にリリースされたブラウザではブラウザ毎に挙動が異なる状況は少なくなりました。
HTML仕様策定まわりの体制変更が仕様策定にも良い影響を及ぼした結果?、jQuery の CSSセレクタ によりDOM要素を検索できる機能同等の機能が、DOM仕様にセレクタAPI(querySelector)として追加され、主要ブラウザに実装されました。
主要ブラウザにセレクタAPIが実装されたことetc により、レガシー・ブラウザを含む各種ブラウザのイベントまわりの挙動etcの差異を吸収するためにコードベースが肥大化しパフォーマンスも悪くなっていたjQueryがフロントエンド
まわりでレガシー扱いされるようになっていきます。
しかし、フロントエンド・エンジニア及びWEBデザイナ の多くに浸透していたこと、便利な jQueryプラグイン が多数存在していること(多くはPure JSでリライトするのがコスト面etcで難しい負の遺産)、DOM(セレクタAPI etc)での記述よりも簡潔に書けること、レガシー・ブラウザのサポートに有用であること、もあり、jQueryはフロントエンドまわりで、未だ一定の支持を得ていて、レガシーでありながら、利用され続けています。
CSSフレームワークであるBootstrapは、5.0.0で、ようやく、jQueryへの依存を取り除きました。
Railsのプロジェクトでも、jQueryはレガシー扱いになっていき、機能の実装に利用したい UIライブラリ が jQueryプラグインの形でしか提供されていないときに、局所的に利用する以外、jQueryを利用しなくなっていて、Railsは2017/04 リリースの 5.1 で jQuery を含めるのをやめ、jQuery依存も除去されています。
(jquery-ujs -> rails-ujs、Turbolinks)
JavaScriptも、ECMA Script4での仕様策定失敗後、Javascript(JS)エンジンの開発者が仕様策定に深く?関与するようになり、追加される機能etcには、まず実装が求められるようになり、JavaScriptの新仕様(ECMA Script〜)は、主要ブラウザの実装が出揃うまで、勧告されないようになっています。
ECMA Script4は、仕様策定参加者の頭の中だけで考えた、机上の空論な(実装の存在しない、実装できない)機能が中核となった仕様でした...。
机上の空論でない機能の多くは、仕切り直した新仕様に含まれて、リリース済みです。
推敲中...
(フレームワークとしての) Rails のニューフェイス、Hotwire
DHHは、2020/12、Turbolinksの発展系 Turbo(JS&Rails)、クライアントJSフレームワークStimulus2.0 と Rails を 組み合わせた、新たな仕組み、Hotwire を発表しました。
Hotwireは、2021/12リリースの Rails7.0 にて、Railsにビルトインされています。
Turbo の発表にあわせメンテナンス・モードに入ったTurbolinksは、なくなり、Turbo Drive(Turbolinks相当)を含む Turbo がRailsに含まれています。
TurbolinksとTurboの間に互換性はあるものの、後方互換は完全ではないです。
Rails 6.2 -> 7.0、のコミット(2021/02/05)にメジャーバージョンアップを必要とする大きな計画がある、とのコメントがあった通り、Hotwire の Rails7.0.0 でのデフォルト化?を含め、Rails7 では割と?大きな変更がいくつも行われています。
Rails 6.2がRails 7になった
Hotwireは、Railsに含まれている機能のみ?で構築されたレガシーなフロントエンドを、比較的、低コストでモダンにできることを売り?にしています。
Hotwire は、rails-ujs + remote: true + js.erb の組み合わせと同じように、jsonではなくhtml(のコード片)を用います、rails-ujs +remote: true + js.erb の発展形(進化形)といえる、と思います。
Hotwireに、rails-ujs + remote: true + js.erb のような不恰好さはありません。
また、Hotwireは、Turbolinksの抱えていた問題を Turbo + Stimulus2 以降 の組み合わせで解消しています。
(既存アプリに Hotwire (beta)を導入して、わかリました。)
Rails しか触ったことのないエンジニアが多いプロジェクトで、Hotwire、流行る、と思います。
RailsでのWEBアプリ開発は、
- フロントエンドは JS(Vue.js、React etc)にお任せ、
バックエンド(WEB API)は Rails - フロントエンドは JS(Vue.js、React etc)と Rails の混在、
JS(Vue.js、React etc)のバックエンド(WEB API)は Rails
(従来のPOST/GETで済む機能はRails、AJAX etcで動的にしたい機能はJS(Vue.js、React etc))
(以前の)2つのスタイルから、
- フロントエンドは JS(Vue.js、React etc)にお任せ、
バックエンド(WEB API)は Rails - フロントエンドは JS(Vue.js、React etc)と Hotwire(Rails)の混在、JS(Vue.js、React etc)のバックエンド(WEB API)は Rails(フロントエンドでの(UIコンポーネント(コンテナ)単位での)混在は可能です。)
- Hotwire (Rails)におまかせ
の3つのスタイルに。
Railsの強みは、バックエンド(サーバーサイド)にあり、フロントエンド(クライアントサイド)が弱いのは当たり前です。
Railsに限らず、フロントエンドの構築をバックエンド(サーバーサイド)系のフレームワーク(のみ)で何とかしようとすると、すぐに限界?が来ます。
バックエンド系のフレームワークはバックエンド(でできること)に専念して、フロントエンドの構築は、フロントエンドのフレームワークに任せる、のが正解です。
逆の、フロントエンド系の言語やフレームワークで、バックエンド(サーバーサイド)を構築しようとした、場合も同様に、すぐに?限界?が来ます。
フロントエンド系の言語やフレームワークはフロントエンドに専念して、バックエンドの構築は、バックエンド系の言語やフレームワークに任せる、のが正解です。
Hotwireの場合、RailsWayを補完?する、フロントエンドのフレームワークを開発して、バックエンド(Rails)と連携させることで、バックエンド系のフレームワークであるRailsの限界を クリアしようとしています。
Hotwireは、Rails(バックエンド)、Stimulus2以降(フロントエンド)、バックエンド (Rails)とフロントエンド(Stimulus2以降)をつなぐTurbo、の構成になっています。
Hotwireが、最近のフロントエンドに求められる機能のうち、どこまでをカバーできるのかは、大凡わかってきています、プロジェクトでHotwireを採用する場合、カバーしている範囲内で事足りる場合は Hotwireオンリーで、事足りない?
場合は 他のJSフロントエンド・フレームワークと混在させる、ことになると思います。
既に、Vue.js、React、etc、のクライアントサイドJSフレームワークをフロントエンドに採用してきている場合も、スルーせずにHotwireを研究?しておくことをオススメします。スルーするならするで OKです。
(受託案件etcで、クライアント?がHotwireを要望している場合は別です。)
Hotwireでできることは、Vue.js、React、etc、のクライアントサイドJSフレームワーク+ Rails の組み合わせ、で、既にできますが、研究?しておいて損はない、と思います。
推敲中...
Railsの中核?ActiveRecord
ActiveRecordなしにRailsなし、と言って(書いて)も過言ではないくらい、よくできたOR(Object Relational)マッパーです。
Ruby以外の言語も含め、様々なORマッパーについて調べたことがあります(つかったことがあるモノもあります)が、これほどよくできたORマッパーに今まで出会ったことがありません。
(個人の好みもあるので、人によっては違うかもしれません。)
これほどよくできたORマッパーは他に存在しないと言って(書いて)も過言ではない、くらい、よくできたORマッパーです。
ActiveRecordのスゴいところは、パフォーマンスに対するモノも含め、改善が続けられていることです。今も、大小様々な改善が日々行われています。
Rails3からのArel、Rails4.2でのAdequateRecordがActiveRecordの改善の代表例かと思います。
ActiveRecordを高速化するAdequateRecordは何をするものか
https://qiita.com/yuku_t/items/bc3728c694ea72bc5478
もちろん、ActiveRecordのみならず、Railsを構成する他の要素の改善も、パフォーマンスに対するモノも含め、日々、行われています。
Railsコミッタ(の多く)は、パフォーマンスに対して敏感、なのだと思います。
そのおかげで、ActiveRecordのN+1問題(ActiveRecordのみならずORマッパー共通? の問題) etcを除いて、パフォーマンスに敏感な(一部の?)ユーザーを除いて、Railsのエンドユーザー(開発者)の大半は、然程、パフォーマンスについて意識することなく、Railsでコードを書けています。
勿論、エンドユーザー(開発者)によるパフォーマンスを意識したコーディングやパフォーマンス・チューニングが必要なケースは(それなりに)あります。
そして、ActiveRecordを含めRailsには、すでに大小様々なサイトでの稼働実績があります。
上述の改善は、そこから得られた知見に基づいて行われてきて、今現在も継続して行われています。
Railsの大小様々なサイトでの稼働により得られた知見は、Rubyにもフィードバックされ、Rubyの改善に活かされています。
AcitveRecordの完成度に迫るORマッパーは中々、出てこない、と思います。
一見良さげに見えるORマッパーが登場しても、完成度を高め、ActiveRecordの完成度に並ぶ or を超える、のは、至難の業と言って(書いて)も過言ではない、です。
ORマッパーは内部でSQLを組み立てます、SQLはANSIで標準化されていますがDB毎に方言があり、ORマッパーはSQLの方言の差異を吸収する必要があります。
SQLのinsert/update/delete 文に方言はありません(ないはず)、方言があるのはselect文 です。
insert/update/delete 文のみをサポートするORマッパーを作るのはわりと簡単です。
select文のうちinner join(内部結合)のみを
サポートするORマッパーを作るのはそんなに難しくないのではないかと思います。
(内部結合に方言はないですし...。)
outer join(外部結合)をサポートしようとすると、実装の難易度が跳ね上がるはずです。
リレーションが複数のテーブルに跨り、階層が深くなっている場合、実装の難易度はさらに高くなるはずです。
方言を吸収し、開発現場で日常的に利用される、様々な条件に基づいたselect文を組み立てられるORマッパーを作るのはかなり大変です、一朝一夕にはいきません。
様々な言語で、これまでに、様々なORマッパーが登場し、その大半が表舞台に立つことなく、表舞台に一瞬立っても表舞台から、消えていきました。
例えば、Rubyなら、消えていったORマッパー
としてDataMapper、表舞台から消えたORマッパーとしてSequel、が有名どころ?です。
ActiveRecordがあるからRailsをつかっている系?のRailsエンジニアは多いはずです。
Railsの強み(の1つ)は、ActiveRecordをビルトインし(組み込み)、Railsの各機能と容易に連携できるように
していることです。
Railsの賞味期限がActiveRecordの賞味期限、ではなく、逆の、ActiveRecordの賞味期限がRailsの賞味期限、と 言って(書いて)も、過言ではない、と思います。
ORマッパーとしてActiveRecordに比肩orを凌駕し、WAFにビルトインでき?WAFの各機能と容易に連携できるORマッパーが他に登場しない限り、 Railsはオワコンにならない、と思います。
そんなORマッパー、当分、登場しない、と自分は
思います。
例えば、サーバーサイドJS実行環境であるNode.js上で動作するORマッパーにDrizzle ORM や Prisma(v2以降)があります。
Prisma(v2以降)は、JavaのORマッパー Torque のように専用のコマンドを叩いて、SQLファイルやデータベースにアクセスするJSクラス?を生成するタイプのORマッパーです。
このタイプの ORマッパーでは、生成コマンドのクオリティが問題になってきます。
複数のテーブルに跨るリレーションに対応した select文の生成をどこまでサポートしているのか、が問題です。
ORマッパでは、select文のサポートの範囲が限られていると採用したプロジェクトの規模が中〜大規模だと、何処かで、生SQLを書くことになります。
生SQLをなるべく書かないで済ませられるなら、それに越したことはない(はず)です。
自分が Prisma のドキュメントetcにざっくり目を通した感じでは、select文のサポート範囲が限られていて、複雑なSQLを、その専用コマンドでは生成できないので、中規模〜大規模のプロジェクトで採用すれば、何処かで、生SQLを書くことになります。
Prismaは 2024/12現在、正式にはSQLの
外部結合をサポートしていません、擬似的にはサポートしています、preview featuresのrelationJoinsで外部結合をサポートしています。
Drizzle ORM は、select文において外部結合をサポートしていますが、複雑なselect文をどこまで組み立てられるかは未知数です(調査していないので、未知数としています)、
現在、開発途上にあるようです。
Drizzle ORM は、Prisama(v2以降)とは異なり、コード生成タイプのORMではありません。
Drizzle ORM も Prisama(v2以降) も、現状、Rails のActiveRecordに取って代われないです、オルタナティブというには、まだまだ弱い気がします。
Drizzle ORM に、ActiveRecord のオルタナティブになれる可能性を感じます。
推敲中&つづく...