webpack + React + Rails5 APIモードで環境構築
バックエンドをRails5のAPIモード、フロントエンドをReactの環境構築をやってみます。webpackも使います。
Rails
まずはAPIモードでRails環境をつくります。
apiモードで始めるには以下のコマンドを打ちます。
rails new sampleapp --api
ファイル一式が完成したら、ディレクトリ移動しておきます。
cd sampleapp/
「rails s」で起動できます。
フロントエンドの環境構築
フロントエンドのコードはclientディレクトリを作り、そこで行います。
./client ├── .babelrc ├── package.json ├── src │ └── app.js ├── webpack.config.js ├── www │ ├── bundle.js │ └── index.html └── yarn.lock
ここで書いた記事とあまり変わらないので参考に
まずは、clientディレクトリを作り、移動します。
mkdir client && cd client
yarnを使いますが、npmでもOKです。
yarn init -y
パッケージをインストールします。
yarn add babel-core babel-loader babel-preset-es2015 babel-preset-react webpack webpack-dev-server -D
Reactも
yarn add react react-dom
.babelrcとwebpack.config.jsを作ります。
touch .babelrc webpack.config.js
それぞれ以下を追記
.babelrc
{ "presets": [ "es2015", "react" ] }
webpack.config.js
const path = require('path'); module.exports = { entry: path.join(__dirname, 'src/app.js'), output: { path: path.join(__dirname, 'www'), filename: 'bundle.js' }, devServer: { contentBase: 'www', port: 4000, inline: true }, module: { loaders: [ { test: /\.js$/, exclude: /node_modules/, loader: 'babel' } ] } };
フロントエンド側のportは4000番にしています。Rails側でデフォルトの3000番を使うので。
必要なディレクトリを作ります。srcディレクトリ以下でコーディングをして、wwwに書き出すようにします。
mkdir src www
必要なファイルを作ります。
touch src/app.js www/index.html
index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>React</title> </head> <body> <div id="app"></div> <script src="bundle.js"></script> </body> </html>
app.js
import React from 'react' import { render } from 'react-dom' class App extends React.Component { render () { return ( <h1>Hello, World!</h1> ) } } render( <App />, document.getElementById('app') )
以下のコマンドを打つと、www以下にbundle.jsができます。
./node_modules/.bin/webpack
package.jsonにscriptを登録します。
package.json
// 省略 "license": "MIT", // ここ追記 "scripts": { "start": "webpack-dev-server" }, "devDependencies": { // 省略
以下のコマンドでlocalhost:4000が立ち上がります。
yarn start
Hello React!と出ればOKです。
Foremanを使う
これでプロジェクトディレクトリ直下で「rails s」を打てばlocalhost:3000でRailsが起動、clientディレクトリ直下で「yarn start」と打てば、localhost:4000でフロントエンドが起動するようになりました。
ただ、いちいちそれぞれを起動するのは面倒です。。。そこでForemanを使います。
ディレクトリの場所を一つ上に戻っておきます。
cd ../
GemfileにForemanを追加し、bandle installします。
Gemfile
source 'https://rubygems.org' git_source(:github) do |repo_name| repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/") end # ここ追記 gem 'foreman' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '~> 5.0.1' # 省略
そして以下を打ちます。
bundle install
次に「Procfile」ファイルを作ります。
touch Procfile
Procfile
rails: bundle exec rails s -p 3000 frontend: cd client;yarn run start
以下を打ち「valid procfile detected (rails, frontend)」と出たらOKです。
foreman check
起動する時は、以下のコマンドを打ちます。
foreman start
起動して、localhost:3000にアクセするとRailsが、localhost:4000にアクセスするとHello React!と出てきます。
これでコマンド一つで同時にそれぞれ起動できるようになりました。
APIを取得してみる
RailsでAPIをつくります。
rails g resource Message text:string
「app/controllers」の中にmessage_controller.rbが作られるので、以下のように修正します。
class MessagesController < ApplicationController def index messages = Message.all render json: messages end end
とりあえず、「db/seeds.rb」でサンプルデータを作ってみます。
Message.delete_all Message.create!([ { text: 'Good morning' }, { text: 'Good afternoon' }, { text: 'Good evening' } ])
以下のコマンドを打ちます。
bundle exec rake db:migrate db:seed
config/routes.rbも修正しておきます。
Rails.application.routes.draw do resources :messages, only: :index, format: 'json' # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html end
rails sで起動し、「localhost:3000/messages.json」にアクセスします。
するとjson形式でGood morningとかいろいろ出てきます。
これをReactで取得してみます。
「client/src/app.js」を以下のように修正します。
import React from 'react' import { render } from 'react-dom' const REQUEST_URL = 'http://localhost:3000/messages.json' class App extends React.Component { constructor(props) { super(props) this.state = { data: [] }; } componentDidMount() { this.fetchData() } fetchData() { fetch(REQUEST_URL) .then((response) => response.json()) .then((responseData) => { this.setState({ data: responseData, }) }) } render(){ return( <ul> {this.state.data.map((item) => { return ( <li key={item.id}>{item.text}</li> ) })} </ul> ) } } render( <App />, document.getElementById('app') )
再び、以下のコマンドで立ち上げます。
foreman start
localhost:4000にアクセスすると、何も表示されないと思います。consoleを見るとエラーが出ていて、localhost3000にアクセスするには許可が入りますと言う感じです。アクセスできるようにもうちょっと修正します。
まずはGemfileの27行目あたりにある「rack-cors」のコメントアウトを外します。なければ追記します。
gem 'rack-cors'
bundle installしておきます。
bundle install
そして、「config/application.rbの下の方にあるコードに追記しておきます。
module Sampleapp class Application < Rails::Application # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. # Only loads a smaller set of middleware suitable for API only apps. # Middleware like session, flash, cookies can be added back manually. # Skip views, helpers and assets when generating a new resource. config.api_only = true # ここ追記 config.middleware.insert_before 0, Rack::Cors do allow do origins 'localhost:4000' resource '*', :headers => :any, :methods => [:get, :post, :put, :delete, :options] end end end end
再び起動
foreman start
今度はlocalhost4000にアクセスすると、以下のようにリスト表示されているはずです。
- Good morning
- Good afternoon
- Good evening
さいごに
APIを作って表示するだけですが、RailsとReactの環境をwebpackを使って作ってみました。次はデータ取得するだけなく、POSTしたりしてみようかと思います。