Rails × React で Rails の scaffold ライクなアプリケーションを実装 - 環境構築 -

Rails×ReactでRailsのscaffoldで生成されるような簡単なcrudができるアプリケーションを実装したので、備忘録として残しておこうと思います。

###**アプリケーションの概要**
タイトルと本文のあるメッセージをCRUD＋絞り込み検索するアプリケーション

###**version**
- Ruby 2.4.1
- Rails 5.1.4
- React 16.2.0
- webpack 3.10.0

###**RailsとReactの役割分担**
- Rails: APIサーバに徹し、jsonを返すだけの役割
- React: Railsへのjsonの受け渡しやルーティング、viewのレンダリングの役割

### **やったこと**
(1) 環境の構築　（本エントリ）
(2) [メッセージ一覧を表示する。](https://qiita.com/hibriiiiidge/items/50c200445a0803ac11b7)
(3) [新規メッセージを作成する。](https://qiita.com/hibriiiiidge/items/5d65d721c605ed597fcb)
(4) [メッセージ詳細の表示、編集、更新をする。](https://qiita.com/hibriiiiidge/items/3dbb022b90b4c21773d2)
(5) [メッセージを削除する、メッセージを検索する。](https://qiita.com/hibriiiiidge/items/e99195771ec145ab68e8)

###**やってないこと**
- Redux、MobXなどステート管理のためのフレームワークの導入
- テストの実装
- CSSの実装
- セキュリティやデータの整合性を確認する実装
- 用語や実装の解説

用語や実装の解説については、参考にさせていただいたサイトのリンクを各実装毎に貼っておりますので、そちらをご確認下さい。
参考サイトの作成者の皆様ありがとうございます。

###**完成イメージ**
![AwesomeScreenshot-2018-02-23T12-34-32-519Z.gif](https://qiita-image-store.s3.amazonaws.com/0/114886/93793cde-b151-d8a1-1a5e-f3d3c5fe31eb.gif)


### **ご一読いただくにあたって**
・間違いがありましたらコメントにて教えて下さい。（まだまだ勉強中です。）


##**環境構築**
####**事前準備**
Ruby/Rails/Node.js/yarn/rbenv/ndenvなどのインストール、設定が必要ですが、解説は実施しませんので以下を参考に準備してください。

- [Rubyのインストール](https://www.ruby-lang.org/ja/documentation/installation/)
- [Ruby on Railsのインストールと設定](https://qiita.com/yu-yan/items/6e693caf23054c6ba9a1)
- [MacにNode.jsをインストール](https://qiita.com/kyosuke5_20/items/c5f68fc9d89b84c0df09)
- [ndenv で Node.js をインストールする際、同時に Yarn もインストールする方法](https://qiita.com/pinemz/items/d758aede73e388c7b57a)
- [Yarn (yarnpkg) インストール覚書](https://qiita.com/kokushin/items/06d2eeb1e95d65cc549b)

あと、私は`zsh`を使っているのですが、PATHを通すのにちょっとハマって、こちらも参考にさせていただきました。

- [zshが「command not found」と云う](https://qiita.com/harapeko_wktk/items/285d5c2a409346e3d55e)

####**Rails**
1.`rails new` でテンプレートを作成します。
 `--api` オプションをつけることで、不要なファイルを生成しないようにします。

```ruby
rails new react_sample --api
```
テンプレートファイルが一式生成されたら、ディレクトリを移動します。

```ruby
cd react_sample
```

Railsサーバーが立ち上がるか確認をします。

```ruby:./react_sample
rails s 
```

`localhost:3000`にアクセスします。

"Yay! You’re on Rails!"の表示が確認できれば成功です。

<img width="699" alt="スクリーンショット 2018-02-06 10.19.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/114886/410912d5-2470-59de-1017-1c00d21e1be2.png">

必要に応じて、`pry`などのgemを入れてもよいかもしれません。
今回は省略します。 

####**React**
Reactの実装は`frontend`ディレクトリを作り、そのディレクトリ内で行います。

```ruby:./react_sample
mkdir frontend && cd frontend
```

`yarn init -y`で`package.json`を作成します。

[Yarn公式サイト　パッケージ](https://yarnpkg.com/lang/ja/docs/creating-a-package/)

```ruby:./react_sample/frontend
yarn init -y                                                                                                                                
yarn init v1.3.2
warning The yes flag has been set. This will automatically answer yes to all questions which may have security implications.
success Saved package.json
Done in 0.02s.
```

Babel関連のパッケージとwebpackをインストールします。

```ruby:./react_sample/frontend
yarn add babel-core babel-loader babel-preset-es2015 babel-preset-react webpack webpack-dev-server -D
yarn add v1.3.2
info No lockfile found.
[1/4] 🔍  Resolving packages...
warning babel-preset-es2015@6.24.1: 🙌  Thanks for using Babel: we recommend using babel-preset-env now: please read babeljs.io/env to update!
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 📃  Building fresh packages...
success Saved lockfile.
success Saved 581 new dependencies.
├─ abbrev@1.1.1
├─ accepts@1.3.4
├─ ansi-regex@2.1.1
├─ ansi-styles@2.2.1
...
├─ yargs-parser@4.2.1
└─ yargs@6.6.0
✨  Done in 15.59s.
```
続けて、ReactとReact-domをイントールします。

```ruby:./react_sample/frontend
yarn add react react-dom
yarn add v1.3.2
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 📃  Building fresh packages...
success Saved lockfile.
success Saved 11 new dependencies.
├─ asap@2.0.6
├─ encoding@0.1.12
├─ fbjs@0.8.16
├─ isomorphic-fetch@2.2.1
├─ node-fetch@1.7.3
├─ promise@7.3.1
├─ prop-types@15.6.0
├─ react-dom@16.2.0
├─ react@16.2.0
├─ ua-parser-js@0.7.17
└─ whatwg-fetch@2.0.3
✨  Done in 4.45s.
```

`.babelrc`ファイルを作って内容を追加して保存します。

```ruby:./react_sample/frontend
touch .babelrc
```

```ruby:./react_sample/frontend/.babelrc
{
  "presets": [
    "es2015", "react"
  ]
}
```
`webpack.config.js`ファイルを作って内容を追加して保存します。

```ruby:./react_sample/frontend
touch webpack.config.js
```

```javascript:./react_sample/frontend/webpack.config.js
const path = require('path');
 
module.exports = {
  entry: path.join(__dirname, 'src/index.js'),
  output: {
    path: path.join(__dirname, 'www'),
    filename: 'bundle.js'
  },
  devServer: {
    contentBase: 'www',
    port: 4000,
    inline: true
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: 'babel-loader',
        exclude: /node_modules/
      }
    ]
  }
};
```

- [webpack.config.jsの読み方、書き方](http://dackdive.hateblo.jp/entry/2016/04/13/123000)

次に、`www`ディレクトリを切って、`index.html`ファイルを作成します。

```ruby:./react_sample/frontend
mkdir www
touch www/index.html
```

```ruby:./react_sample/frontend/www/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>
```

次に、`src`ディレクトリを切って、`index.js`ファイルを作成します。

```ruby:./react_sample/frontend
mkdir src
touch src/index.js
```

```javascript:./react_sample/frontend/src/index.js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';

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

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

次に、`bundle.js`なるものを作成します。
`./node_modules/.bin/webpack`のコマンドを叩きます。

`bundle.js`とは、ざっくり説明すると、webpackにより、`index.js`を始めとする複数存在するファイル（`*.js`, `*.css`）が一つのファイルとしてまとめられて、セットされるファイルのようです。 `index.html` で呼び出します。

- [最新版で学ぶwebpack 3入門(図解付き)](https://ics.media/entry/12140)
- [webpackの基本的な使い方](http://walking-succession-falls.com/webpack%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9/)

```ruby:./react_sample/frontend./node_modules/.bin/webpack
Hash: xxxxxxxxxxxxxxxxxxxxx
Version: webpack 3.10.0
Time: 2278ms
    Asset    Size  Chunks                    Chunk Names
bundle.js  729 kB       0  [emitted]  [big]  main
  [14] ./src/index.js 2.27 kB {0} [built]
    + 26 hidden modules
```

最後に、フロントエンドのファイルを配信する開発用サーバーを起動するコマンドを、`package.json`の`scripts`として追加します。

```json:./react_sample/frontend/package.json
{
  "name": "frontend",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  ↓追加　========================
  "scripts": {
    "start": "webpack-dev-server"
  },
  ↑追加　========================
  "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "webpack": "^3.10.0",
    "webpack-dev-server": "^2.11.1"
  },
  "dependencies": {
    "react": "^16.2.0",
    "react-dom": "^16.2.0"
  }
}
```

以上で、Reactの環境設定は終わりです。

以下のコマンドを叩いて、`http://localhost:4000/`にアクセスして見ます。

```ruby:./react_sample/frontend
yarn start
```

"Hello, Rect" と表示されれば成功です。
<img width="496" alt="スクリーンショット 2018-02-06 10.12.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/114886/cd82b370-89e7-324a-ec89-eb69e2a41b97.png">

以上の設定でAPI用サーバー（Rails）, フロントエンド用サーバー（React含む）各々が立ち上がるようになったと思います。
./react_sample直下で`rails s` => `localhost:3000`
./react_sample/frontend直下で`yarn start` => `localhost:4000`

この時点ではディレクトリは以下のようになっているかと思います。
<img width="296" alt="スクリーンショット 2018-02-06 23.03.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/114886/3200661b-9e8b-bf48-2dc6-b08498a52902.png">


`foreman`というrailsのgemを使うことにより、コマンド1つで両方のサーバーを立ち上げることもできるようなので、気になる方は調べて見てください。

環境構築はできましたので、次にメッセージ一覧を表示するを実装したいと思います。[こちら](https://qiita.com/hibriiiiidge/items/50c200445a0803ac11b7#_reference-db1fb7a3e12f323ca722)