RailsでWebpackerを使おう

ka

2018-07-29

Author

ka

Gravatar

Website: kaosfield

Twitter: ka

GitHub: kaosf

License

CC BY-NC-SA 4.0

Copyright (C) 2018 ka

このページとリポジトリ

https://kaosf.github.io/20180729-tokushimarb-slide

Repository: kaosf/20180729-tokushimarb-slide - GitHub

準備

Dockerのインストール (DBのため)

Node.jsとYarnのインストール (Webpackerのため)

Rubyのインストール (言わずもがな)

準備

DBコンテナ

sudo docker run -d --restart=always -p 15432:5432 postgres:10.3

または

sudo docker run -d --restart=always -e MYSQL_ALLOW_EMPTY_PASSWORD=yes -p 13306:3306 mysql:5.7.22

これに

で接続するのが簡単で環境を汚しません

※SQLite3を使うのは個人でやるもの以外ではよほどの理由が無い限りやめましょう

Railsプロジェクト

rails new my_webpacker_app -d postgresql
# or
bundle exec rails new my_sample_app -d mysql
# などなど…

webpacker導入

Gemfileに以下を追加して

gem 'webpacker', '3.5.0'

Gemfile.lock更新

bin/bundle install
# or
bin/bundle install --path vendor/bundle

Railsプロジェクト(初期化時に実は…)

実はRails 5.1からは

rails new --webpack

オプションが使えました(気付かなかった)

と言ってもGemfileの更新までやってくれてるだけっぽいので気にしなくて良いです(多分)

webpacker導入

bin/rails webpacker:install

時間掛かります

bin/yarn install

時間掛かります

Bootstrap導入

bin/yarn add bootstrap

package.jsonは手動で編集しない方が良いです

yarn.lockも同時に変更されます

Bootstrap導入

app/javascript/packs/application.jsを編集

-console.log('Hello World from Webpacker')
+import '../stylesheet'

app/javascript/stylesheet.scssを作成

@import "~bootstrap/scss/bootstrap";

なんか変な感じですがWebpackerで扱うCSSはapp/javascript内に置きます

rails-ujs復活

bin/yarn add rails-ujs

rails-ujs復活

app/javascript/packs/application.jsを以下のように編集します

 // layout file, like app/views/layouts/application.html.erb

+import Rails from 'rails-ujs'
+Rails.start()
+
 import '../stylesheet'

これが無いと例えばRailsがscaffoldで生成するdestroyアクションのあのボタンとかがちゃんと動きません

webpacker導入

app/views/layouts/application.html.erbを編集

-    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
-    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
+    <%= javascript_pack_tag 'application' %>
+    <%= stylesheet_pack_tag 'application' %>

参考 https://github.com/rails/webpacker#usage

これでwebpackerの導入はおしまい

後は

bin/rails assets:precompile

を通常通りに行います

成果物が public/packs に出来上がるのでこれを本番環境にコピーしてやります

※本番環境で作らないのか?という理由は後ほど

Rubyコンテナ

本番稼働時の想定

永続化するものを確保する場所作成

sudo mkdir -p /var/docker/rails
sudo mkdir /var/docker/rails/bundle
sudo mkdir /var/docker/rails/log
sudo mkdir /var/docker/rails/tmp
sudo mkdir /var/docker/rails/pack
sudo chmod o+w /var/docker/rails/pack

※別に /var/docker とかで無く /Users/yourname/foo/bar でも何処でも良いです

Rubyコンテナ

本番稼働時の想定

※今のディレクトリ($PWD)がRailsのプロジェクトルートだとします

sudo docker run -it \
  -v $PWD:/app \
  -v /var/docker/rails/bundle:/usr/local/bundle \
  -v /var/docker/rails/log:/app/log \
  -v /var/docker/rails/tmp:/app/tmp \
  -v /var/docker/rails/pack:/app/public/pack \
  -w /app \
  -p 3000:3000 \
  -e TZ=Asia/Tokyo \
  -e DATABASE_URL=postgres://postgres:@172.17.0.1:15432/db \
  -e RAILS_ENV=production \
  -e RAILS_MASTER_KEY=xxxx \
  -e RAILS_SERVE_STATIC_FILES=1 \
  ruby:2.5.1 bash

MySQLの人は

  -e DATABASE_URL=mysql2://root:@172.17.0.1:13306/db \

に読み替えて下さい

Rubyコンテナ

RAILS_MASTER_KEYにはconfig/master.keyの値を設定して下さい(※勝手に作られてるはず)

※コンテナから見たホストが 172.17.0.1 になります

※ネットワークを別途構築したりした場合の解説は省略

Rubyコンテナ

Bundlerがgemをインストールする場所は /usr/local/bundle です

参考: 該当箇所

bin/bundle install --path vendor/bundle

しても結局 .bundle ディレクトリが作られない(設定が保存されない)ので --path vendor/bundle オプションは使わないが吉

gemをインストールした状態を使いまわしたいなら大人しくホストに永続化して /usr/local/bundle にマウントしましょう

もしくは Dockerfile でgemのインストールまで終わらせたイメージでも作っておいてプライベートレジストリに上げておくとデプロイは多分これが一番早いと思います

Yarn

残念ながらRubyのオフィシャルコンテナにはYarnは入っていません

インストールするにはDockerfileに以下を追記すると良いでしょう

# Node.js
ENV PATH /root/.nodebrew/current/bin:$PATH
RUN curl -L git.io/nodebrew | perl - setup && \
  nodebrew install-binary v9.11.2 && \
  nodebrew use v9.11.2

# Yarn
RUN apt-get update && apt-get -y install apt-transport-https && \
  curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
  echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
  apt-get update && apt-get -y install yarn

参考

CSS, JavaScriptの用意

手元で作っておいた public/packs/*/var/docker/rails/packs にコピーすればOKです

sudo rm /var/docker/rails/packs/*
sudo cp public/packs/* /var/docker/rails/packs

Railsサーバ起動前の開発完了

db/schema.rbをきちんと用意しておきます

config/database.ymlを以下のように編集しておきます

   # http://guides.rubyonrails.org/configuring.html#database-pooling
   pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
+  user: <%= ENV.fetch("DB_USER") { 'postgres' } %>
+  password: <%= ENV.fetch("DB_PASSWORD") { '' } %>
+  host: <%= ENV.fetch("DB_HOST") { '127.0.0.1' } %>
+  port: <%= ENV.fetch("DB_PORT") { 5432 } %>

 development:

MySQLの人はデフォルト値を root, 3306 などとしておきましょう

Railsサーバ起動前の開発完了

export DB_PORT=15432
# export DB_HOST=example.com # 必要に応じて追加
bin/rails db:create
bin/rails db:migrate

※開発時にDATABASE_URLを指定するのはdevelopmentとtestのDB名が衝突するため非常に面倒になるのでやめときます

※ていうか今回の所詮デモであれば config/database.yml に直書きしても支障はありません

Railsサーバ起動前の開発完了

bin/rails g controller home index

app/views/home/index.html.erb編集

<div class="container">
  <div class="row">
    <div class="col-4">col-4</div>
    <div class="col-8">col-8</div>
  </div>
  <div class="row">
    <div class="col-md-4 col-sm-12">col-md-4 col-sm-12</div>
    <div class="col-md-8 col-sm-12">col-md-8 col-sm-12</div>
  </div>
</div>

Railsサーバ起動前の開発完了

本番環境でJSのランタイムが無いよと言われないようにしておきます

Gemfilemini_racerというgemのコメントアウトを外してbin/bundle installします

Rails起動

Rubyのコンテナで動いているbash上で以下を実行すればOKです

bin/bundle install
bin/rails db:setup
bin/rails s

※雑ですが本気でやりたい人は config/puma.rb をちゃんと編集して

bin/bundle exec pumactl start

とかやって下さい

開発時Tips

bin/webpack-dev-server

を起動しておく(※bin/rails sと別に)と,CSSやJSを編集したときにブラウザを自動で更新してくれます

便利