Webpacker+ReactでRailsのフロントを開発する準備

2019.01.27

事前準備

  • VagrantでAmazon Linuxを立ち上げる
  • Ruby on Rails 5.1.6.1の動作環境を構築する
  • yarnやnodejsをセットアップする

Ruby on Railsアプリケーションを新規に作成する



# アプリケーションを置くディレクトリに移動
$ cd /var/www

# Railsアプリケーションを立ち上げ
# -T:Test::Unitを使わない
# ーB:bundle installを行わない
# -d mysql:データベースはMySQLを利用
# --webpack:Webpackerを利用
$ rails new . -T ーB -d mysql --webpack

--webpackオプションをつけることによって、Gemfileに以下の行が追加される。



gem 'webpacker'

Gemfileにmini_racerを追加する

以下の行をGemfileに追記する。



gem 'mini_racer', platforms: :ruby

Gemをインストールする



$ bundle install --path=vendor/bundle --jobs=4

この後のコマンドでどうRailsアプリケーションが変わっていくのか見るためにGitのコミットをしておく

Ruby on Railsではコマンドを利用して設定ファイルやアプリケーションのコードを生成することも多々あるので、それによってどんな変化が起きるか把握しづらい。Gitでプロジェクトを管理しておくことで、コマンド実行前後でどう変わるのかが明確に把握できるので、新しいGem等を試す際には非常におすすめ。



# Gemのインストール先のvendor/bundleはGit管理外に指定
$ echo 'vendor/bundle' >> .gitignore

# RubyMineが生成するディレクトリもGit管理外に指定
$ echo '.idea' >> .gitignore

# Gitでコミット
$ git add .
$ git commit -m "initial commit"

Webpackerの初期設定を行う



$ bundle exec rails webpacker:install

自動的にyarnが起動してパッケージのインストールも行われた。 このコマンドを実行したあとにGitで差分を確認すると以下のようになった。



$ git add .
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	new file:   .babelrc
	modified:   .gitignore
	new file:   .postcssrc.yml
	new file:   app/javascript/packs/application.js
	new file:   bin/webpack
	new file:   bin/webpack-dev-server
	modified:   config/environments/development.rb
	modified:   config/environments/production.rb
	new file:   config/webpack/development.js
	new file:   config/webpack/environment.js
	new file:   config/webpack/production.js
	new file:   config/webpack/test.js
	new file:   config/webpacker.yml
	modified:   package.json
	new file:   yarn.lock

各変更の内容を簡単にまとめると以下の通り。

ファイル 変更内容
.babelrc Babelの設定
.gitignore yarnのログ、Webpackによってビルドされた成果物のディレクトリ、node_modulesなどを除外する設定が追加
.postcssrc.yml PostCSSの設定
app/javascript/packs/application.js フロントエンドのJavaScriptのエントリポイント
bin/webpack Webpackでフロントエンドのソースをビルドするスクリプト
bin/webpack-dev-server Webpackでフロントエンドのソースを監視して自動ビルドするサーバーを起動するスクリプト
config/environments/development.rb config.webpacker.checkyarnintegrityの設定が追加
config/environments/production.rb config.webpacker.checkyarnintegrityの設定が追加
config/webpack/environment.js 共通のWebpackのビルド設定を記述するファイル
config/webpack/development.js development環境でのWebpackのビルド設定を記述するファイル
config/webpack/production.js production環境でのWebpackのビルド設定を記述するファイル
config/webpack/test.js test環境でのWebpackのビルド設定を記述するファイル
config/webpacker.yml Webpackerの設定を記述するファイル
package.json JavaScriptのパッケージのバージョンを記述したファイル
yarn.lock インストールされたパッケージの依存関係を記述したファイル

またここでGitでコミットしておく。



$ git commit -m "webpacker:installを実行"

WebpackerでReactを使うための初期設定を行う



$ bundle exec rails webpacker:install:react

このコマンドを実行したあとにGitで差分を確認すると以下のようになった。



$ git add .
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	modified:   .babelrc
	new file:   app/javascript/packs/hello_react.jsx
	modified:   config/webpacker.yml
	modified:   package.json
	modified:   yarn.lock

各変更の内容を簡単にまとめると以下の通り。

ファイル 変更内容
.babelrc presetsのセクションに"react"が追加
app/javascript/packs/hello_react.jsx Helloというコンポーネント(サンプル)
config/webpacker.yml extensionsにjsxが追加された
package.json React関係のパッケージが追加された
yarn.lock React関係のパッケージの依存関係が追加された

またここでGitでコミットしておく。



$ git commit -m "webpacker:install:reactを実行"

ひとまずRailsのローカルサーバーを起動してWebアプリケーションにアクセスできるようにする



# データベースを作成
$ bundle exec rails db:create
Created database 'www_development'
Created database 'www_test'

# データベースのマイグレーションを実行
$ bundle exec rails db:migrate

# Pumaを起動
$ bundle exec rails s -b 0.0.0.0
=> Booting Puma
=> Rails 5.1.6.1 application starting in development
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.12.0 (ruby 2.4.3-p205), codename: Llamas in Pajamas
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000

Macのブラウザからhttp://localhost:3000にアクセスしてみる。

Webpacker+ReactでRailsのフロントを開発する準備

無事いつもの画面が表示された。 データベースのマイグレーションに伴ってdb/schema.rbが生成されるのでそれもコミットしておく。



$ git add .
$ git commit -m "データベースを準備"

サンプルとして生成されたHelloコンポーネントを表示してみる

まずは画面を作る。



Rails.application.routes.draw do
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html

  root to: 'home#home' # この行を追加
end



class HomeController < ApplicationController
  def home
  end
end



<h1>Home#home</h1>

この時点でhttp://localhost:3000にアクセスすると以下のように表示される。

Webpacker+ReactでRailsのフロントを開発する準備

ここで一旦コミットしておく。



$ git add .
$ git commit -m "空の画面を作成"

続いて、Webpackerでビルドされたファイルを読み込むための実装を行う。



<!DOCTYPE html>
<html>
  <head>
    <title>Www</title>
    <%= csrf_meta_tags %>

    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <%= yield %>

    <%= javascript_pack_tag 'hello_react' %> <!-- この行を追加 -->
  </body>
</html>

これで準備完了。http://localhost:3000にアクセスすると以下のように表示される。

Webpacker+ReactでRailsのフロントを開発する準備

なお、Webpackでビルド対象となっているディレクトリ内のファイルに変更があると、HTTPリクエストのタイミングでWebpackがビルドするので少々時間がかかる。$ bundle exec rails s -b 0.0.0.0を実行しているターミナル上では以下のように表示されている。



Started GET "/" for 10.0.2.2 at 2019-01-27 19:34:14 +0900
Cannot render console from 10.0.2.2! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by HomeController#home as HTML
  Rendering home/home.html.erb within layouts/application
  Rendered home/home.html.erb within layouts/application (0.3ms)
[Webpacker] Compiling…
[Webpacker] Compiled all packs in /var/www/public/packs
Completed 200 OK in 3870ms (Views: 3867.4ms)

webpack-dev-serverを使うことでビルドを自動化する

今の状態だと、Webpackのビルド対象に入っているディレクトリ内のファイルが変更された後の1回目のHTTPリクエストのタイミングでビルドされる。この状態だと、作業としては「ファイルを変更する」→「ブラウザを再読み込み」という流れになる。フロントエンドのアプリケーションが大きくなるとビルド時間も長くなってきてしまう。

webpack-dev-serverを使うと、Webpackのビルド対象に入っているディレクトリ内のファイルが変更されたタイミングで自動的にビルドを行い、ビルド完了時にブラウザを自動的に再読み込みしてくれる。

また、Hot Module Replacementと呼ばれる機能により、画面全体を再読み込みしなくてもJavaScriptアプリケーションの部分だけを再読み込みすることもできる。

まずはWebアプリケーションのプロセスとwebpack-dev-serverを同時に立ち上げるのに便利なGem「foreman」をインストールする。



$ echo -e "\\ngem 'foreman'" >> Gemfile
$ bundle install

procfile.devというファイルをRailsアプリケーションのディレクトリの直下に以下の内容で作成する。



web: bundle exec rails s -b 0.0.0.0 -p 3000
webpacker: ./bin/webpack-dev-server

$ rails sの方は-p 3000を明示的に指定しないとなぜかポート5000番で起動してしまった)

これで以下のコマンドを実行すると、自動的にPumaとwebpack-dev-serverを起動してくれる。



$ bundle exec foreman start -f procfile.dev

これでフロントエンドのコードを変更するとwebpack-dev-serverのプロセスがビルドを行ってくれて、完了したタイミングでブラウザをリロードしてくれるようになった。

Vagrantでwebpack-dev-serverを使う際の注意点

1:webpack-dev-serverが使う3035番ポートを仮想マシンに流す設定をVagrantfileに追加する必要がある



config.vm.network "forwarded_port", guest: 3035, host: 3035

2:webpack-dev-serverが3035番ポートで外部からのアクセスを受け付ける設定を追加する必要がある

dev_serverのセクションhostpublicの値を以下のように変更する。



  dev_server:
    host: 0.0.0.0
    public: 0.0.0.0:3035

参考