Skip to content

Rails 7のjsbundling-railsを使ってReactやVue.jsをモダンに統合する方法

はじめに

Rails 7は、フロントエンドの扱い方に大きな変革をもたらしました。かつての標準だったWebpackerは廃止され、よりシンプルでモダンなJavaScriptのエコシステムと直接連携するアプローチが採用されました。その中心となるのが**jsbundling-rails** gemです。

jsbundling-railsは、esbuild, Rollup, WebpackといったモダンなJavaScriptバンドラをRailsアプリケーションに統合するための橋渡し役となります。これにより、開発者はRailsの流儀に縛られることなく、JavaScriptコミュニティで標準となっているツールチェインを使って、ReactやVue.js、Svelteといったコンポーネントベースのライブラリを効率的に利用できるようになりました。

この記事では、jsbundling-railsの基本的な仕組みを解説し、新しいRails 7アプリケーションにReactを導入する具体的な手順を紹介します。

jsbundling-railsの役割

jsbundling-railsは、それ自体がJavaScriptをバンドル(複数のJSファイルを一つにまとめること)するわけではありません。その役割は非常にシンプルです。

  1. package.jsonで定義されたbuildスクリプト(例: "build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds")を、rails assets:precompileタスク実行時や、開発サーバー起動時に自動で実行する。
  2. バンドルされた成果物(app/assets/buildsディレクトリに出力される)を、RailsのAsset Pipelineから参照できるようにする。

つまり、JavaScriptのバンドル処理そのものはesbuildやWebpackといった専門のツールに完全に任せ、Railsはそれを呼び出して結果を受け取るだけ、というクリーンな関心の分離が実現されています。

Rails 7 + Reactのセットアップ手順

それでは、rails newコマンドを使って、Reactを統合した新しいRailsアプリケーションを作成してみましょう。

ステップ1: rails newコマンドの実行

rails new時に、--javascript(または-j)オプションで利用したいバンドラを指定します。ここでは、デフォルトで最も高速なesbuildを選択します。Reactを導入する場合、--cssオプションでbootstraptailwindなどを指定しておくと、後のスタイリングが楽になります。

bash
# esbuildとBootstrapを使って新しいRailsアプリを作成
rails new my_react_app -j esbuild --css bootstrap

このコマンドを実行すると、jsbundling-railscssbundling-railsGemfileに追加され、package.jsonにはesbuild@hotwired/stimulusなどが設定された状態でプロジェクトが初期化されます。

ステップ2: Reactのインストール

次に、作成されたRailsアプリケーションのディレクトリに移動し、npm(またはyarn)を使ってReactと関連ライブラリをインストールします。

bash
cd my_react_app

npm install react react-dom

ステップ3: Reactコンポーネントの作成

JavaScriptのエントリーポイントはapp/javascript/application.jsです。ここにReactコンポーネントをマウント(描画)するためのコードを記述します。

まず、Reactコンポーネントを作成しましょう。

bash
mkdir -p app/javascript/components
touch app/javascript/components/HelloWorld.js

app/javascript/components/HelloWorld.js

jsx
import React from 'react';

const HelloWorld = ({ greeting }) => {
  return (
    <div className="container py-4">
      <h1>{greeting}</h1>
      <p>This is a React component rendered by Rails!</p>
    </div>
  );
};

export default HelloWorld;

ステップ4: エントリーポイントでのコンポーネントの登録

次に、application.jsからこのHelloWorldコンポーネントを呼び出し、Railsのビューに描画するための「糊」となるコードを書きます。

javascript
// app/javascript/application.js
import React from 'react';
import { createRoot } from 'react-dom/client';
import HelloWorld from './components/HelloWorld';

// Railsのビュー側にある <div id="react-root"></div> にコンポーネントを描画する
document.addEventListener('DOMContentLoaded', () => {
  const container = document.getElementById('react-root');
  if (container) {
    const root = createRoot(container);
    // Railsのビューから渡されたデータをpropsとしてコンポーネントに渡す
    const props = JSON.parse(container.getAttribute('data-props'));
    root.render(<HelloWorld {...props} />);
  }
});

このコードは、DOMContentLoadedイベント(ページのHTMLが完全に読み込まれたとき)を待ち、ページ内にid="react-root"という要素があれば、その要素をReactのコンポーネントで置き換える、という処理を行っています。

ステップ5: Railsビューからの呼び出し

最後に、Railsのビューファイルに、ReactコンポーネントをマウントするためのDOM要素を設置します。

app/views/static_pages/home.html.erb (このビューを表示するためのコントローラとルートは別途作成してください)

erb
<%# Reactコンポーネントに渡したいデータをJSON形式でdata-props属性に設定 %>
<div id="react-root" data-props="<%= { greeting: 'Hello from Rails View!' }.to_json %>"></div>
  • id="react-root": application.jsがコンポーネントをマウントする場所の目印です。
  • data-props属性: ビューからReactコンポーネントにデータを渡すための一般的な方法です。ハッシュを.to_jsonでJSON文字列に変換して埋め込み、JavaScript側でJSON.parseして利用します。

ステップ6: 開発サーバーの起動

準備は完了です。bin/devコマンドで開発サーバーを起動します。

bash
./bin/dev

このコマンドは、foreman(またはovermind)を使って、RailsサーバーとJavaScriptのビルドプロセス(npm run build -- --watch)を同時に起動してくれます。app/javascript以下のファイルを変更すると、esbuildが自動で再バンドルを行い、ブラウザをリロードすれば変更が反映されます。

指定したページにアクセスすると、"Hello from Rails View!"というメッセージがReactコンポーネントによって描画されているはずです。

まとめ

jsbundling-railsは、RailsとモダンなJavaScript開発の間の溝を埋める、シンプルかつ強力な接着剤です。

  • rails new -j [esbuild|rollup|webpack] で好みのバンドラを選択してプロジェクトを開始できる。
  • JavaScriptの依存関係はpackage.jsonで、ビルド方法はbuildスクリプトで管理する、というJavaScriptの標準的な作法に従う。
  • ./bin/devコマンドがRailsサーバーとJSのビルドプロセスをまとめて管理してくれる。

このアプローチにより、Rails開発者はフロントエンドの技術選定において高い自由度を得ることができます。Railsの堅牢なバックエンドと、ReactやVueが提供する豊かなコンポーネントエコシステムを組み合わせ、生産性とユーザー体験の両方を最大化させましょう。

AI が自動生成した技術記事をまとめたテックブログ