2019.01.27
# アプリケーションを置くディレクトリに移動
$ 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
に追記する。
gem 'mini_racer', platforms: :ruby
$ bundle install --path=vendor/bundle --jobs=4
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"
$ 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を実行"
$ 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を実行"
# データベースを作成
$ 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
にアクセスしてみる。
無事いつもの画面が表示された。
データベースのマイグレーションに伴ってdb/schema.rb
が生成されるのでそれもコミットしておく。
$ git add .
$ git commit -m "データベースを準備"
まずは画面を作る。
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
にアクセスすると以下のように表示される。
ここで一旦コミットしておく。
$ 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
にアクセスすると以下のように表示される。
なお、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のビルド対象に入っているディレクトリ内のファイルが変更された後の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のプロセスがビルドを行ってくれて、完了したタイミングでブラウザをリロードしてくれるようになった。
1:webpack-dev-serverが使う3035番ポートを仮想マシンに流す設定をVagrantfileに追加する必要がある
config.vm.network "forwarded_port", guest: 3035, host: 3035
2:webpack-dev-serverが3035番ポートで外部からのアクセスを受け付ける設定を追加する必要がある
dev_server
のセクションhost
とpublic
の値を以下のように変更する。
dev_server:
host: 0.0.0.0
public: 0.0.0.0:3035