見出し画像

【React】+【RailsAPI】 create-react-app を使ったアプリ [1] 環境構築

概要

フロントに React、バックエンドに Rails(APIモード)を使うアプリの環境構築を行います。Rails プロジェクトを APIモードで作成し、その中に React プロジェクトを含んだ形の構成です。React プロジェクトは create-react-app を利用して作成します。

create-react-app 

1つのコマンドを実行して最新のWebアプリを設定します。
Webpack や Babel といったツールのインストール、設定が不要です。
コードに集中出来るよう事前に設定され、隠されています。
プロジェクトを作成するだけで良いのです。

素晴らしい。

バージョン

ruby:2.5.1
rails:5.2.2
react:16.8.4
react-scripts:2.1.8

Rails 側の実装

APIモードで Rails アプリを作成

$ bundle exec rails new . --database=postgresql --api

RailsAPIの実装
何らかモデル、コントローラーなどを作成し
render json: @todos のように、jsonデータを返す実装を行う。

$ bundle exec rails g model todo
$ bundle exec rails db:migrate

$ bundle exec rails g controller todos

実装例

class TodosController < ApplicationController
 def index
   @todos = Todo.all
   render json: @todos
 end
 def create
   @todo = Todo.create(params[:todo])
   render json: @todo
 end
 def update
   @todo = Todo.find(params[:id])
   @todo.update(params[:todo])
   render json: @todo
 end
 def destroy
   @todo = Todo.find(params[:id])
   if @todo.destroy
     head :no_content, status: :ok
   else
     render json: todo.errors, status: :unprocessable_entity
   end
 end
end

ルーティングの追加

Rails.application.routes.draw do
 resources :todos
end

Rails をポート3001で起動

$ bundle exec rails s -p 3001

curlで疎通を確認

$ curl http://localhost:3001/todos/

# -> []
# 空配列が返ってくる


React 側の実装

create-react-app をインストール

$ yarn global add create-react-app

# もしくは
$ npm install -g create-react-app

React プロジェクトの作成
Rails アプリのルートディレクトリ上で React プロジェクトを生成する。

$ create-react-app <React のプロジェクト名>

# 例
$ create-react-app front_end

RailsAPI を実行するためのモジュールを追加
axios
ブラウザおよび node.js 用の Promise ベースの HTTPクライアント。Get や Post などを Promise による非同期通信で実行出来る。

# App.js
class App extends React.Component {
  componentDidMount() {
   axios
     .get(`${this.host}todos`)
     .then(res => {
       console.log(res.data)
     })
     .catch(data => {
       console.log(data)
     })
 }

React を実装
axios を使って何らか React アプリを実装。

React を起動
yarn start でポート3000で起動する。

$ cd <React のプロジェクト名>
$ yarn start

これで一応 React から RailsAPI を呼んで、レスポンスで state を更新して再描画する簡単な流れが実装出来たと思います。

CORSポリシー対応

ブラウザのコンソールログにエラーが表示されている。

Access to XMLHttpRequest at 'http://localhost:3001/todos' from origin 
'http://localhost:3000' has been blocked by CORS policy: 
No 'Access-Control-Allow-Origin' header is present on the requested resource.

異なるドメイン間(ここではポート3000<->ポート3001)の通信は
CORS(Cross-Origin Resource Sharing)の設定が必要のため、
Rails 側で通信を許可するドメインを指定する。

rack-cors Gem のインストール
Gemfile の gem 'rack-cors' のコメントを外してインストールする。

gem 'rack-cors'
$ bundle


許可するアクセス元URLを設定する(変数に入れるだけ)

# application.rb
config.x.cors_allowed_origins = ENV.fetch('CORS_ALLOWED_ORIGINS', 'http://localhost:3000')

任意に作成した環境変数から、React 側のドメインを取得しておく。
現段階では「CORS_ALLOWED_ORIGINS」環境変数を設定していないため、デフォルト値の「http://localhost:3000」が設定される。

※本番環境ではこの環境変数に、本番の React を動かしているサーバーのURLを指定する。

許可するアクセス元URLを指定する

# config/initializers/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
 allow do
   origins Rails.application.config.x.cors_allowed_origins
   resource '*',
     headers: :any,
     methods: [:get, :post, :put, :patch, :delete, :options, :head],
     credentials: true
 end
end

先ほど取得した値を origins で指定し、クロスドメインのアクセスを許可することで、先ほどのエラーが解消される。

BootStrap、Sass の導入

必須でもないので割愛。

ESLint や Prettier の導入

ESLint
静的解析ツール。コーディングのルールを設定して、ルールに沿っていないものは警告出したりエラーにして、エディタ上などで通知してくれる。

Prettier
コードフォーマッタ。コーディングのルールを設定して、それに沿った形でコードをフォーマットしてくれる(空白や改行の入れ方など)。

どちらも純粋に生産性が上がるので入れた方が良いですが、何が正解というのもないので参考リンクだけ紹介します。
(対応の順番としては React プロジェクト作成時点です)

ESLintでReact.js / ES6+ のコードをチェックする手順
airbnb スタイルでルールを拡張しているようです。

AtomでESLintとPrettierをAirbnbルールで使う
こちらも airbnb スタイルですが、シンプルにデフォルトのまま。
加えて Prettier の導入と、Atom でのインストールや有効化も記載されています。

create-react-app の依存関係の解消

依存バージョンを何も考えず ESLint の導入を行なっていたら、React アプリ起動時にエラーが出るようになりました。

Create React Appが提供するreact-scriptsパッケージには、依存関係が必要です。
"babel-eslint": "9.0.0"
手動でインストールしようとしないでください。パッケージマネージャが自動的にインストールします。
しかし、異なるバージョンのbabel-eslintがツリーの上位で検出されました。

babel-eslint 10.0.1 がインストールされていたため入れ直して対応しました。

$ yarn remove babel-eslint
$ yarn add --dev babel-eslint@9.0.0

# eslint も同様のエラーが発生したため対応
$ yarn remove eslint
$ yarn add --dev eslint@5.12.0

あとがき

モダンJSに触りたかったのと、jQuery で DOM を触るんじゃなく、値(コンポーネント)に集中出来る React が面白そうなので勉強中です。

C#などの経験はあり JS は全く使ったことなかったですが、JavaScript おじさん寺子屋 でざっくり学べました(JS というより React 開発に向けた前準備といった感じですが)。CodeSandBox 上で学ぶ形のため、こちらも Webpack などの周辺環境構築を気にすることなく集中出来ます。
またこの方の Udemy の React アプリ開発コースも React 初心者でもとても分かりやすい内容でオススメです(回し者ではないですが、購入の際は Qiita記事 上部のリンク先だと35%割引になります)。

次回は割愛した BootStrap などの導入か、本番環境へのデプロイ周りを書こうかなと思います。

この記事が気に入ったらサポートをしてみませんか?