RailsのプロジェクトでRailsとReactでWebサービスを作る場合観察する限り以下の2パターンかと思うのですがそれぞれどういった場合に選択するべきか自分なりの考えをまとめてみます。
Reactの場合で書いてますが多分Vueとかでも同じ考えになるはず。
パターン1
RailsをAPIモードで使いフロントエンドの機能(アセットパイプライン)は一切使わない。フロントは独立したReactのコードで実装してローカルでは別ポート、デプロイ時は別サーバ/ドメインにデプロイする
パターン2
react-rails gemを使いwebpackerを使ってアセットパイプラインの中にnpmやyarnと一緒にreactのコードを埋め込む
https://github.com/reactjs/react-rails
まず結論
新規プロジェクトならパターン1の方が良いです。それなりの規模のアセットパイプラインで実装されたフロントエンドを抱えていてこれからerb、slimなどのテンプレートエンジンをReactのコードに置き換えたい場合パターン2を選ぶべきかと思います。
パターン1のRailsをAPIモードで使ってフロントとバックを分離するアーキテクチャを推す理由
まずフロントとバックエンドの結合がなくなるからです。
パターン2のアセットパイプラインにwebpackerでreactのコードを埋め込む場合Gemfileでバックエンドのライブラリを依存関係を管理しフロントエンドのライブラリはyarnやnpmで依存関係を管理することになるわけですが、フロントとバックエンドがwebpackerで繋がっているのでバックエンドのバージョンとフロントエンドのバージョンが乖離するとコンパイルエラーになってフロントエンドのコードが正確に描画されない。。みたいなことが起こってこれがめっちゃ辛い。
またアセットパイプラインのコードは大きくコンパイルにも時間がかかるのでローカルでの開発やデプロイの時間も無視できないレベルで膨らみます。
あとHTML、CSS、JSをまとめて最適化する処理はRubyで行うのではなくフロントエンドのライブラリで実行するのが大きな時代の流れなのは間違い無いと思うのでできればアセットパイプラインは切った方がいいかなと。
パターン2を使うべき場面は?
正直Reactがあればアセットパイプラインを使う意味はほぼないと思うのですが既に大規模なerb、slimなどのテンプレートエンジンを使って実装されたコードがある場合、それらを全てReactのjsxコードに置き換えるのは工数的に厳しい場合が多いと思います。
その場合react-railsを使って既存のコードにReactを差し込んでいく形が現実的になると思います。
パターン1のデメリットは?
パターン1(RailsをAPIモードにしてフロントと分離する)のデメリットとして以下はあると思います。
Gemのdeviseなどが使えなくなるのでセッションの仕組みを理解していないとユーザログイン機能が作れない
デプロイ構成が変わる。今までRailsはEC2やFagateのような仮想サーバ、コンテナサービスにデプロイして終わりだったがフロントエンドを別でデプロイする場合S3を使うとかVercelを使うなど別のノウハウが必要になるのでインフラのキャッチアップコストはかかると思います。
が、この辺りは情報量も多く今の時代、ある程度時間をかけてググればすぐキャッチアップできると思うのでそこまでのデメリットでは無いのかなと。