Rails 5.1のwebpack (gem無し)を使ってReact, Redux, Material-UIの環境構築


Published on

Rails の View を React にする場合のお手軽な環境構築としては少し前なら react-rails や react_on_rails といった Gem を使って統合していた。それも Rail 5.1 になって Gem 無しでもカンタンに環境構築が可能になった。もちろん Gem を使えばそれらに付随する機能が使えて便利な面もあるが、「無しでもカンタンにできる」というのはありがたい。また Rail 標準としては「これから JavaScript フォルダ配下の pack に React 関連コードを置きます」とかやられると、一応 Rails 標準というものを知っておいた方がよさそう。
ということで Rails 5.1 の webpack (gem 無し)を使って React, Redux, Material-UI の環境構築を書いた。

$ ruby -v
ruby 2.3.3
$ rails -v
Rails 5.1.1
$ npm -v
4.0.5

rails のバージョンが 5.1 であることを確認した後、rails new を--webpack=react 指定で実行する。
実行後の出力結果を見ると webpackt やら yarn があることが分かる。


rails new myapp --webpack=react
 :
 :
Using rails 5.1.1
Using sass-rails 5.0.6
Bundle complete! 17 Gemfile dependencies, 71 gems now installed.
Use `bundle show [gemname]` to see where a bundled gem is installed.
       rails  webpacker:install
Copying webpack core config and loaders
      create  config/webpack
      create  config/webpack/configuration.js
 :
 :
$ brew upgrade yarn
success Saved 562 new dependencies.
├─ [email protected]
├─ [email protected]
├─ [email protected]
├─ [email protected]
 :
 :
yarn add v0.23.4
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 📃  Building fresh packages...

フォルダ構成が以下のようになっている。これからは app/javascript/packs 配下に入れるのが標準とのこと。


app/javascript
└── packs
    ├── application.js
    └── hello_react.js

packs に入っている hello_react.js はこのように単純な React component。
単に Hello React と出力しているだけ。早速これを使って動作を確認してみる。

import React from 'react'
import ReactDOM from 'react-dom'
class Hello extends React.Component {
  render() {
    return <div>Hello {this.props.name}!</div>
  }
}
document.addEventListener('DOMContentLoaded', (e) => {
  ReactDOM.render(<Hello name="React" />, document.body.appendChild(document.createElement('div')))
})

サンプルの動作を見るために以下のコマンドで pages controller を作る。

    bundle exec rails g controller pages index

pages の index.html.erb に javascript_pack_tag を追記する。

# app/views/pages/index.html.erb

<h1>Pages#index</h1>
<%= javascript_pack_tag 'hello_react' %>

javascript_pack_tag のロードを有効にするため webpack-dev-server の設定を development.rb に記載。


# config/environments/development.rb

Rails.application.configure do
 :
 :
  config.x.webpacker[:dev_server_host] = "http://127.0.0.1:8080"
end

サンプルの動作を確認するため rails サーバーを立ち上げる。

    bundle exec rails server

別のターミナルから以下のコマンドを実行し webpack-dev-server を立ち上げる。つまり rails sserver だけではサンプルを見ることができない。


./bin/webpack-dev-server --host 127.0.0.1
  :
  :
  [164] ./app/javascript/packs/application.js 515 bytes {1} [built]
  [266] multi (webpack)-dev-server/client?http://127.0.0.1:8080 ./app/javascript/packs/application.js 40 bytes {1} [built]
     + 70 hidden modules
webpack: Compiled successfully.

ここでローカルホストの以下のページにアクセスする。Hello React が見えたら無事に動いていることになる。
http://localhost:3000/pages/index

image

この時点では React が入っているだけで Redux, Material-UI がまだ入っていない。
以下のコマンドで入れる。

npm install --save redux
npm install --save react-redux
npm install --save-dev redux-devtools
npm install --save material-ui
npm install --save react-tap-event-plugin

コマンド実行後に package.json を確認すると以下のようにインストールされていることが分かる。


{
  "name": "myapp",
  "private": true,
  "dependencies": {
    "autoprefixer": "^7.0.1",
    "babel-core": "^6.24.1",
    "babel-loader": "7.x",
    "babel-preset-env": "^1.4.0",
    "babel-preset-react": "^6.24.1",
    "coffee-loader": "^0.7.3",
    "coffee-script": "^1.12.5",
    "compression-webpack-plugin": "^0.4.0",
    "css-loader": "^0.28.1",
    "extract-text-webpack-plugin": "^2.1.0",
    "file-loader": "^0.11.1",
    "glob": "^7.1.1",
    "js-yaml": "^3.8.4",
    "material-ui": "^0.18.1",
    "node-sass": "^4.5.2",
    "path-complete-extname": "^0.1.0",
    "postcss-loader": "^2.0.5",
    "postcss-smart-import": "^0.7.0",
    "precss": "^1.4.0",
    "prop-types": "^15.5.10",
    "rails-erb-loader": "^5.0.0",
    "react": "^15.5.4",
    "react-dom": "^15.5.4",
    "react-redux": "^5.0.4",
    "react-tap-event-plugin": "^2.0.1",
    "redux": "^3.6.0",
    "sass-loader": "^6.0.5",
    "style-loader": "^0.17.0",
    "webpack": "^2.5.1",
    "webpack-manifest-plugin": "^1.1.0",
    "webpack-merge": "^4.1.0"
  },
  "devDependencies": {
    "redux-devtools": "^3.4.0",
    "webpack-dev-server": "^2.4.5"
  }
}

以降は Redux やら Material-UI を使ってコードを書く。そこは長くなりそうなので書くとしても別記事にする予定。

結果としてはこんな感じでよくある Material-UI 風のページができあがる。個人的には Bootstrap は飽きたので Material-UI がいいと思っている。フォーム押したときの下線がヒューっと出る動作とかが気持ちいい。

関連記事