Rails 5.1からwebpackやYarnがサポートされフロントエンドの開発環境構築が非常にやりやすくなったと聞いたので自分でも試してみました。ただそんな中でも、そもそもRailsの知識に乏しいためもあってか割と苦労したので振り返りつつやり方を整理したいと思います。
環境
vagrantでCentOS7の仮想サーバーを建て、その中で作業していきます。
また、今回はrailsのgemをシステム全体に入れるのではなく、プロジェクト配下にのみ入れることを想定して環境を構築していきます。
$ cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)
$ rbenv -v
rbenv 1.1.1-28-gb943955
$ rbenv versions
* 2.4.3 (set by /home/vagrant/.rbenv/version)
$ ruby -v
ruby 2.4.3p205 (2017-12-14 revision 61247) [x86_64-linux]
$ bundler -v
Bundler version 1.16.1
$ nvm --version
0.33.8
$ node -v
v9.3.0
$ yarn -v
1.3.2
$ psql -V
psql (PostgreSQL) 10.1
Railsプロジェクトの作成
まずはRailsプロジェクトのディレクトリを作成してそこに移動します
$ mkdir sample-app
$ cd sample-app
Gemfileを作成して、編集します
$ bundle init
Writing new Gemfile to /home/vagrant/sample-app/Gemfile
$ vi Gemfile
railsの行がコメントアウトになっているので#記号を削除して保存します
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
gem "rails"
Gemfileに記載されたgemをパスを指定してインストールします
bundlerについては次の記事に簡潔にまとめて頂けているので、まだ知識が曖昧という方はこれを機にぜひ読んでみてください。
$ bundle install --path vendor/bundle
Fetching gem metadata from https://rubygems.org/..........
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies...
Fetching rake 12.3.0
Installing rake 12.3.0
~~~ 省略 ~~~
Fetching rails 5.1.4
Installing rails 5.1.4
Bundle complete! 1 Gemfile dependency, 38 gems now installed.
Bundled gems are installed into `./vendor/bundle`
これで rails
コマンドが使えるようになったので、 rails new
でアプリを作っていきます。
話の本筋とはズレますが、React導入に必要なwebpackオプションに加えて、DBをデフォルトのSQLiteからPostgreSQLに変更するためのオプションも渡しています。
ちなみに --webpack=react
というオプションについて先に解説すると、裏で
bundle exec rails webpacker:install
bundle exec rails webpacker:install:react
という2つのコマンドを行ってくれるものです。
$ bundle exec rails new . --webpack=react --database=postgresql
exist
create README.md
create Rakefile
create config.ru
create .gitignore
conflict Gemfile
Overwrite /home/vagrant/sample-app/Gemfile? (enter "h" for help) [Ynaqdh]
Gemfileを上書きしてもいいかと聞かれますので y を入力してEnterを押します。
force Gemfile
run git init from "."
Reinitialized existing Git repository in /home/vagrant/sample-app/.git/
create app
create app/assets/config/manifest.js
create app/assets/javascripts/application.js
~~~ 省略 ~~~
run bundle install
~~~ 省略 ~~~
Fetching ffi 1.9.21
Installing ffi 1.9.21 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native
extension.
~~~ 省略 ~~~
An error occurred while installing ffi (1.9.21),
and Bundler cannot continue.
Make sure that `gem install ffi -v '1.9.21'` succeeds
before bundling.
In Gemfile:
selenium-webdriver was resolved to 3.9.0, which depends
on
childprocess was resolved to 0.8.0, which depends on
ffi
rails webpacker:install
~~~ 省略 ~~~
bundle install の途中でエラーが出てしまいました。
エラーの内容を見てみると、 ffi という gem のインストールに失敗しているようです。
また、ffi は webpacker:install コマンドに必要なようで、こちらも後で実行し直す必要がありそうです。
解決方法を探るために rubygems で ffi を検索してみます。
見てみると、February 06, 2018 (2018/02/06)に最新バージョンが出ているようです。
(執筆している現在は2018/02/10)
ひとまずバージョンを一つ前のものを指定してもう一度インストールしてみます。
バージョンを指定してインストールするために、Gemfileに次の1行を追加します。
$ vi Gemfile
gem 'ffi', '1.9.18'
保存したらもういちど bundler で gem をインストールします。
$ bundle install
The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.
Fetching gem metadata from https://rubygems.org/.........
Fetching gem metadata from https://rubygems.org/.
Resolving dependencies....
Using rake 12.3.0
~~~ 省略 ~~~
Fetching ffi 1.9.18
Installing ffi 1.9.18 with native extensions
Fetching childprocess 0.8.0
Installing childprocess 0.8.0
~~~ 省略 ~~~
Fetching webpacker 3.2.1
Installing webpacker 3.2.1
Bundle complete! 18 Gemfile dependencies, 72 gems now installed.
Bundled gems are installed into `./vendor/bundle`
無事にgemのインストールが完了しました。
それでは次に --webpack=react
オプションによって裏で実行してもらえる予定だったのに、gem のインストールに失敗したせいで実行されることのなかったコマンドを手動で実行していきます。
====================
※ ちなみに先ほど rails new
コマンドをする際には先頭に bundle exec
をつけて実行しましたが、 rails new
コマンドを実行してRailsプロジェクトを作成したあとはbinディレクトリ配下にrailsコマンドが準備されるため、 bundle exec rails
の代わりに bin/rails
としても実行できるようになります。
$ ls bin/
bundle rails rake setup update yarn
ただし、混乱を避けるために本記事中では今後も bundle exec
としてrailsコマンドを実行していきます。
====================
$ bundle exec rails webpacker:install
create config/webpacker.yml
Copying webpack core config
create config/webpack
create config/webpack/development.js
create config/webpack/environment.js
create config/webpack/production.js
create config/webpack/test.js
Copying .postcssrc.yml to app root directory
create .postcssrc.yml
~~~ 省略 ~~~
Done in 41.74s.
Webpacker successfully installed 🎉 🍰
webpacker のインストールが完了しました。
続けて React のインストールです。
$ bundle exec rails webpacker:install:react
Webpacker is installed 🎉 🍰
Using /home/vagrant/sample-app/config/webpacker.yml file for setting up webpack paths
Copying react preset to your .babelrc file
Copying react example entry file to /home/vagrant/sample-app/app/javascript/packs
~~~ 省略 ~~~
Done in 46.42s.
Webpacker now supports react.js 🎉
webpack、Reactのインストールが完了しました。
binディレクトリの中を確認すると webpack
webpack-dev-server
コマンドが新たに追加されていることが確認できます。
$ ls bin/
bundle rails rake setup update webpack webpack-dev-server yarn
以上でRails、webpack、Reactの入ったRailsプロジェクトの完成です。
動作確認
まずはRailsが動作しているかを確認するためにサーバーを起動します
$ bundle exec rails s
サーバーを起動したらブラウザのアドレス欄に localhost:3000
と入力してページを開きます。
次のような画面が出ればRailsは動作しています。
(2018/4/11 追記)
vagrantfileに次の一行を追加してホストOSとゲストOSでポートフォワーディングする必要があります。
config.vm.network "forwarded_port", guest: 3000, host: 3000
Railsの動作確認ができたら次はReactの動作確認をします。
Railsサーバーは Ctrl + C で一旦止めておきます。
Reactの動作確認をするには一手間必要になります。
まずはHelloコントローラーを作成します。
$ bundle exec rails g controller hello index
次にルーティングを書き換えます。
$ vi config/routes.rb
Rails.application.routes.draw do
root to: 'hello#index'
end
レイアウトファイル app/views/layouts/application.html.erb
を編集します。
JavaScriptをインクルードするヘルパーメソッドを javascript_include_tag
から javascript_pack_tag
に変更します。
$ vi app/views/layouts/application.html.erb
~~~ 省略 ~~~
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
~~~ 省略 ~~~
javascript_pack_tag
は、先ほどインストールしたの webpacker という gem が提供するヘルパーメソッドです。
このメソッドを使用すると、 JavaScript が app/assets/javascripts/
ではなく、 app/javascript/packs/
配下のものがインクルードされるようにRailsの動作が変わります。
React をインストールすると app/javascript/packs/
にサンプルの hello_sample.jsx
が作成されています。
$ ls app/javascript/packs/
application.js hello_react.jsx
このサンプルファイルを読み込むように次のように設定を変更します。
$ vi app/javascript/packs/application.js
~~~ 省略 ~~~
console.log('Hello World from Webpacker')
require('./hello_react.jsx') // この行を追加
jsx ファイルをコンパイルして js ファイルを作成します。
コンパイルをするためには次のコマンドを実行します。
$ bin/webpack-dev-server
Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.
何やらエラーが出ているのでメッセージ通りにコマンドを実行します。
$ bundle binstubs bundler --force
再度コンパイルを実行します。
$ bin/webpack-dev-server
10% building modules 2/2 modules 0 active
Project is running at http://localhost:3035/
webpack output is served from /packs/
Content not from webpack is served from /home/vagrant/sample-app3/public/packs
~~~ 省略 ~~~
webpack: Compiled successfully.
コンパイルに成功し、 webpack-dev-server が起動しました。
この状態でもう一つコンソールを起動してRailsプロジェクトのルート階層に移動します。
※ Macの場合 command + t でターミナルのタブを複製できます。再度vagrant sshで仮想サーバーに接続します。
$ cd sample-app
Railsサーバーを起動します。
$ bundle exec rails s
ブラウザで localhost:3000 にアクセスし、「Hello React!」が表示されれば Rails 上で React が動いています。