Rails
React

RailsのフロントエンドにwebpackでビルドされたReactを使うための設定

概要

Railsアプリケーション内でフロントエンドにReactを利用するための設定をする。(2018/11/6時点)
Railsアプリケーションの作成から、Railsのフォルダ内にフロントエンドのためのフォルダを作成し、
ビルド、Rails起動でReactで実装したものが見れる部分までの設定を行う。

実行環境

  • Rails 5.2.1
  • node 8.11.4
  • npm 5.6.0

Railsプロジェクトの作成

こちらの記事など参考にしていただけると嬉しいです。
ローカル環境に諸々をインストールせずにRails新プロジェクトを作成する - Qiita
また、Reactで作成したjsファイルを反映させる対象のページを作成します。
以下のファイルをそれぞれ編集・作成します。

config/route.rb
Rails.application.routes.draw do
  root to: 'home#index'
end
app/controllers/home_controller.rb
class HomeController < ApplicationController
  def index
  end
end
app/views/home/index.html.erb
<div id="app"></div>
<%= javascript_include_tag 'webpack/app.js' %>

Railsプロジェクトのconfig/initializes/assets.rbに以下の記述を追加します。

config/initializes/assets.rb
Rails.application.config.assets.precompile += %w( webpack/app.js )

また、このままではRailsのprecompileにビルドしたファイルが含まれ、読み込み時にエラーが発生するため、
app/assets/javascripts/application.jsに以下を追加します。
これは、本来require_treeで全て読み込まれるはずのjsファイルの対象から、指定したファイルを除外するための命令を記述しています。

app/assets/javascripts/application.js
//= stub webpack/app

この時点では、Reactによるjsファイルが作成されていないため、実行はできません。

Reactプロジェクトの作成

新規作成したRailsプロジェクトの中にfrontフォルダを作成します。

$ mkdir front && cd front

frontフォルダ内でnpmライブラリのインストールを行います。

$ npm init -y
# -Dは--save-devの意味
$ npm install -D webpack webpack-cli
$ npm install -D @babel/core babel-loader @babel/preset-env @babel/preset-react
# -Sは--saveの意味
$ npm install -S react react-dom

frontフォルダ内にsrcフォルダを作成し、App.jsとindex.jsを作成します。

front/src/App.js
import React from "react";

class App extends React.Component {
  render() {
    return (
      <div>
        <h1>Hello React!</h1>
      </div>
    );
  }
}

export default App;
front/src/index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";

ReactDOM.render(<App />, document.getElementById("app"));

webpackを使用したビルド設定を行う

.babelrcを作成します。

front/.babelrc
{
  "presets": ["@babel/env", "@babel/react"]
}

webpack.config.jsを作成します。

front/webpack.config.js
// Railsアプリのパスを指定するのに必要
const path = require("path");

module.exports = {
  entry: {
    app: "./src/index.js"
  },
  output: {
    // Railsアプリのassets内にビルドしたファイルを置くように設定
    path: path.resolve(__dirname, "../app/assets/javascripts/webpack"),
    filename: "[name].js"
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: {
          loader: "babel-loader"
        },
        exclude: /node_modules/
      }
    ]
  }
};

開発の利便性のためにpackage.jsonに開発用ビルドコマンドを追加します。

front/package.json
{
  // ...省略
  "scripts": {
     "webpack-watch": "webpack -w"
  },
  // ...省略
}

frontディレクトリ内で以下のコマンドを叩くことでファイルのビルド・監視を行えるようになっているか確認します。
app/assets/javascripts/webpack/app.jsが作成されていたらOKです。

$ npm run webpack-watch

また別のターミナルを開いてRailsアプリケーションを起動してみます。

$ bundle exec rails server

http://localhost:3000 にアクセスし、このような画面が表示されていたら完了です。
スクリーンショット 2018-11-06 23.19.09.png