はじめに
※ この文章はベータ版です。
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.2.0では、YJITは、実戦投入可能なレベルには達しているものの、
デフォルトでは off になっています。3.3.0では、YJITは改良され、
パフォーマンスが大幅に?改善しています。)
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 が14年ちょい前の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の自動生成機能、複合プライマリキーのサポート etc が
追加されています。
8.0で、Sprockets → Propshaft やPWAサポートの追加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の適用されるコードは全ての
コードではないので、(JIT有効時に)同じくスクリプト言語である PHPや
Pyton(の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を採用して
います(勿論、処理速度が要求される場面では他の言語も併用して
います。)
Railsの次期バージョン(7.2?)では、2023/12 リリース予定の
Ruby3.3.0以降で動作させている場合、YJITがデフォルトで
有効になります。
推敲中...
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 を オススメします。
Rails6 + Simpacker を採用している、Railsでの開発プロジェクト、
今でも結構あるのではないか、と思います。
Rails6での、Webpacker から jsbundling-rails (or Simpacker)
へのリプレース、低コストで行える、と思います。
(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 (WIP)
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パッケージの導入を
サポートする形に実装が変更されています。)
Rails6では、Webpackerオンリー
or Webpacker + Sprockets4
で、JS/CSS のライブラリを管理する、形が
主流になっています。
Rails6では、Webpacker + Sprockets4
では、node_modules下
は NPM etc で管理し、Sprockets4 には node_modules下を参照
させるのみです。
Rails7 (Hotwire) でも、JS / CSS の管理は、Yarn or NPM で行う
のが主流になっています。
(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の1.0以前のバージョンでの
本番採用は見合わせたほうが無難です。)
Propshaft は、0.6.4以降から、node_modules下(に導入された
外部ライブラリ(css/js))を扱えますが、Propshaftで直接扱うと、
現状(0.7.0)では、パフォーマンスの低下に繋がるので、
node_modules下は、基本、モジュールバンドラー or DartSass
etc のツール 経由で扱い、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
速報: Basecampがリリースした「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になった
https://techracho.bpsinc.jp/hachi8833/2021_02_08/103801#1-2 )
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)
の混在、バックエンド(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は
外部結合をサポートしていません、擬似的にサポートしてはいる
ようです。)
Drizzle ORM は、select文において外部結合をサポートしていますが、
複雑なselect文をどこまで組み立てられるかは未知数です、現在、
開発途上にあるようです。
Drizzle ORM は、Prisama(v2以降)とは異なり、コード生成タイプの
ORMではありません。
Drizzle ORM も Prisama(v2以降) も、現状、Rails のActiveRecord に取って代われないです、オルタナティブ という
には、まだまだ弱い気がします。
Drizzle ORM に、ActiveRecordのオルタナティブ になれる
可能性を感じます。
推敲中&つづく...