Reactを利用するために、フロントエンドビルドツールであるwebpackを利用して開発をすすめます。
Reactをビルドするにあたり、webpackをそのまま利用する方法と、Railsからwebpackを簡単に利用できるようにしたwebpackerというGemを使う方法があります。
webpackをそのまま利用する
- 利点
- Railsに詳しくなくても扱える(ビルドはRailsとは独立して考えればよい)
- 欠点
- ボイラープレート(アプリの雛形)や Create React App などのツールを使わないと初期の環境構築が難しい
- RailsとReactを同時にデプロイする仕組みを考える必要がある
webpackerを利用する
- 利点
- 複雑なwebpackの設定ファイルが隠蔽されているので、webpackに慣れていない場合でも容易に環境構築ができる
- Railsのアセットと一緒にwebpack buildしたアセットも容易にデプロイできる
- ヘルパーが用意されており、RailsのViewからwebpackerでビルドしたファイルを簡単に呼び出せる
- 欠点
- webpackの最新版にWebpackerが追いついていかない(=最新バージョンをすぐに利用できない)おそれがある
webpackをそのまま利用するかwebpackerを利用するかは、システムの設計方針によっても変わります。
Railsとフロントエンド(Javascript/View)を完全に分離して開発したい場合はwebpackをそのまま利用すべきです。 逆にRailsのエコシステムにのりつつReactを導入したい場合はwebpackerを利用するのをおすすめします。
webpackを利用して、Hello Worldを作成しましょう。
Create React App を利用すると、新規の設定済みReact + Webpack プロジェクトを容易に作成でき、 複雑なwebpackの初期設定をしなくて済みます。
Javascriptのパッケージマネージャには、以降yarnを利用します。 次のコマンドでインストールしてください。
npm install -g yarn
Create React App はグローバルなパッケージとしてインストールする必要があります。
yarn global add create-react-app
Create React App をインストール後、次のコマンドでReactアプリを作成します。
create-react-app hello-react
コマンド実行後に次のファイルが生成されます。
$ tree -I 'node_modules'
.
├── README.md
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ └── registerServiceWorker.js
└── yarn.lock
作成したreactプロジェクトディレクトリ内で、次のコマンドを使い development 環境で開発用サーバを起動します。
yarn start
起動後に表示されているアドレスにアクセスすると、Reactアプリが表示されることを確認してください。
src/App.js には画面表示用のコンポーネントがあります。
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to React</h1>
</header>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
</div>
);
}
}
export default App;
h1タグ、Welcome to React の文字列を適当なものに変更すると、 自動でビルドが走り画面に表示された文字列が変化していることを確認してください。
yarn build コマンドを利用することで、作成したReactアプリのProduction用js/cssファイルを作成することができます。
$ yarn build
yarn run v1.1.0
$ react-scripts build
Creating an optimized production build...
Compiled successfully.
File sizes after gzip:
38.06 KB build/static/js/main.a3b22bcc.js
299 B build/static/css/main.c17080f1.css
build ディレクトリ以下に作成されたファイルは、そのままサーバに配置することができます。
$ tree build/
build/
├── asset-manifest.json
├── favicon.ico
├── index.html
├── manifest.json
├── service-worker.js
└── static
├── css
│ ├── main.c17080f1.css
│ └── main.c17080f1.css.map
├── js
│ ├── main.a3b22bcc.js
│ └── main.a3b22bcc.js.map
└── media
└── logo.5d5d9eef.svg
4 directories, 10 files
webpackerを利用してReactをビルドしてみましょう。 webpackerはRubyのgemでありwebpackのラッパーでもあります。webpackerはRailsと組み合わせて使うことを想定しています。
以下手順でRailsアプリからReactを呼び出します。
gemコマンドを使ってRailsを導入します。
gem install rails
rails new コマンドで新規Rails + Reactアプリケーションを作成します。
rails new hello-react-rails --webpack=react --database=mysql
作成したRailsアプリディレクトリの中で次のコマンドを実行し、データベースの初期化をします。
bundle exec rake db:create db:migrate
この状態でRailsを起動してみましょう。 次のコマンドでサーバを起動することができます。
bundle exec rails server
更に、Webpackでのビルドをするために webpack-dev-server も別途起動する必要があります。
bin/webpack-dev-server
ブラウザで http://0.0.0.0:3000 にアクセスすると、次のようなRailsの初期画面が表示されることを確認してください。
Hello World表示用の Controller/View を作成します。 次のコマンドで indexアクションを持った DashboardsController を作成します。
bundle exec rails generate controller dashboards index
app/controllers/dashboards_controller.rb 、app/views/dashboards/index.html.erb が新規作成されます。
class DashboardsController < ApplicationController
def index
end
end
<h1>Dashboards#index</h1>
<p>Find me in app/views/dashboards/index.html.erb</p>
config/routes.rb には routingが追加されています。
Rails.application.routes.draw do
get 'dashboards/index'
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
Controller、View、およびRoutingを追加することで、画面にアクセスできるようになります。
http://0.0.0.0:3000/dashboards/index にアクセスすると、次の画面が表示されます。
HTMLは app/views/dashboards/index.html.erb に記述します。 中身を適当な文字列に書き換えて画面を更新してみてください。
webpackを使ってビルドするjavascriptファイルは、app/javascript 以下に配置します。 app/assets/javascript ではないので注意してください。
app/javascript 以下は webpacker (webpack) でビルドされるファイルを配置し、 app/assets/javascript は Sprocketsでコンパイルするファイルを配置します。
SprocketsとはRailsが利用しているアセット管理用のライブラリで、js/css等のアセットのコンパイル等を担っています。 SprocketsではES6のコンパイルはできませんので、ES6形式のJSは app/javascript に配置しwebpackにビルドさせましょう。
app/javascript/packs/hello_react.jsx に以下ファイルを配置します。 RailsのViewから直接呼び出すエントリーポイントとなるjavascriptは、app/javascript/packs 以下に配置する必要があります。
// app/javascript/packs/hello_react.jsx
import React from 'react'
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'
const Hello = props => (
<div>Hello {props.name}!</div>
)
Hello.defaultProps = {
name: 'David'
}
Hello.propTypes = {
name: PropTypes.string
}
document.addEventListener('DOMContentLoaded', () => {
ReactDOM.render(
<Hello name="React" />,
document.body.appendChild(document.createElement('div')),
)
})
このファイルをViewから呼び出してみましょう。 app/views/dashboards/index.html を以下のように書き換えます。
<h1>Dashboards#index</h1>
<p>Find me in app/views/dashboards/index.html.erb</p>
<%= javascript_pack_tag 'hello_react' %>
hello_react の部分は app/javascript/packs 以下のファイル名を指定します。 この状態でdashboards/index画面を更新してみましょう。
Hello React! という部分は React を使ってレンダリングしています。
app/javascript/packs/hello_react.jsx の Hello コンポーネントを次のように書き換えてみましょう。
import React from 'react'
import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'
class Hello extends React.Component {
render() {
return (
<div>
こんにちは、React。<br />
props は {this.props.name} のように利用できます。
</div>
);
}
}
Hello.defaultProps = {
name: 'David'
}
Hello.propTypes = {
name: PropTypes.string
}
document.addEventListener('DOMContentLoaded', () => {
ReactDOM.render(
<Hello name="React" />,
document.body.appendChild(document.createElement('div')),
)
})
画面をリロードすると次のように表示されます。