DockerでRailsチュートリアルのローカル開発環境構築 - WebpackでBootstrapとFont Awesomeを導入 -


はじめに

Dockerでローカル開発環境構築を行い、Railsチュートリアルを再走しております

  • Railsチュートリアル最新版(2020.8.6現在)に対応のRails 6
  • Dockerを使用し、開発環境の再現が可能
  • なるべくローカル環境にインストールしない

今回はRailsチュートリアルの5章に相当する部分です

3章, 4章の内容は特に問題になりませんが、

5章 5.1.2 BootstrapとカスタムCSS の部分でいよいよWebpackの沼に突入して行きます

具体的にはgemを利用せず, YarnとWebpackでBootstrapやFont Awesomeを導入、管理します

加えてテストを書くことが増えるのでその辺りをRSpecで置き換えて進めていきます

5章終了時のブランチはfilling-in-layoutです
https://github.com/dev-naokit/sample_app_on_docker/tree/filling-in-layout

第一回
DockerでRailsチュートリアルのローカル開発環境構築(Rails 6 + PostgreSQL + Webpack) - Qiita

第二回
DockerでRailsチュートリアルのローカル開発環境構築 - RSpec導入 & CircleCIでHerokuデプロイ- - Qiita

個人開発アプリ
mdClip <オンラインmarkdownエディタ>

Dockerのコンテナ上で操作する場合はターミナルのコマンドを適宜

$ docker-compose run app ...

もしくは

$ docker-compose exec app ...

で置き換えてください。

BootstrapとFontawesomeの導入

Rails 6ではJavaScriptのモジュールバンドラとしてWebpackが導入されていますが、
画像やCSSに関しては従来のSprocketがアセットパイプラインとして使用され、
JavaScriptのみをWebpackでコンパイルするようになっています

application.html.erb

<head>の内容を書き換えます

app/views/layouts/application.html.erb

<head>
  <title><%= full_title(yield(:title)) %></title>
  <%= csrf_meta_tags %>
  <%= csp_meta_tag %>
  <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
  # (下の行を追記)webpackがCSSを扱えるようにする
  <%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
  # JavaScriptはデフォルトでwebpacerが pack フォルダをコンパイルして出力している
  <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
  <!--[if lt IE 9]>
      <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/r29/html5.min.js">
      </script>
    <![endif]-->
</head>

YarnでBootstrapをインストール

<追記>
この記事のTroubleshootやこの先の記事でも触れますがBootstrapのバージョンが異なることで、CSSのセレクタやHTMLのクラスを書き直す必要が出てきます。よほどこだわりが無ければオリジナルのRailsチュートリに合わせる方が良いかと思います

yarn addでpackegeのバージョンを指定する

7章のTroubleshoot
コンテナ上のデバッグ環境構築 - DockerでRailsチュートリアルのローカル開発環境構築 - - Qiita
Yarn公式
yarn add | Yarn

jquerypopperはBootstrapに必要なパッケージ
Font Awesomeもあとで必要になるのでインストールします
('@fortawesome'は誤字ではありません)

yarn add bootstrap jquery popper.js @fortawesome/fontawesome-free

インストールされたモジュールは
package.jsonで確認できます

application.js

app/javascript/packs/application.js

以下を追記します

require("bootstrap");
require("@fortawesome/fontawesome-free");

require('jquery')も併記するような情報もありましたが、
Bootstrapが自動的にrequire('jquery')してくれるようでココには記述不要です

私も色々不具合を検証している過程で
require('jquery')がなくてもjqueryがロードされることに気づいたのですが
jqueryの多重起動はJavaScriptの動作不具合につながることもあるようで、
現状はこのまま進めます

(下に参考記事を貼っておきます)

environment.js

jQueryをどこからでも呼び出せるようにする

config/webpack/environment.js

const { environment } = require('@rails/webpacker')
var webpack = require('webpack');

environment.plugins.append(
    'Provide',
    new webpack.ProvidePlugin({
        $: 'jquery/src/jquery',
        jQuery: 'jquery/src/jquery',
        Popper: ['popper.js', 'default']
    })
)

module.exports = environment

こうすることで毎回import $ from 'jquery';と書かなくて良くなるとのことです

CSS

app/javascript/stylesheets/application.scss(新規作成)

以下追記

@import '@fortawesome/fontawesome-free/scss/fontawesome';
@import 'bootstrap/scss/bootstrap';

application.js

app/javascript/packs/application.js

以下を追記します

import '@fortawesome/fontawesome-free/js/all';
import "../stylesheets/application.scss";

参考

Rails 6: Webpacker+Yarn+Sprocketsを十分理解してJavaScriptを書く: 前編(翻訳)|TechRacho(テックラッチョ)〜エンジニアの「?」を「!」に〜|BPS株式会社

Rails 6+Webpacker開発環境をJS強者ががっつりセットアップしてみた(翻訳)|TechRacho(テックラッチョ)〜エンジニアの「?」を「!」に〜|BPS株式会社

CSSの扱いについて

JavaScriptだけでなく画像やCSS、全てをWebpackでコンパイルすることも可能なようです

現状はSprocketによるアセットコンパイルと、Webpackerが共存している状況に変わりはなく

app/javascript/stylesheets/...をコンパイルした内容が<head>内の

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

で出力され

app/assets/stylesheets/...をコンパイルした内容が同じく<head>内の

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

に出力されている状況です

つまりチュートリアル通りassets内のCSS, SCSSを編集しても、
packs内のCSS, SCSSを編集してもビューに反映される状況が出来上がっています

BootstrapやFont Awesomeのstyleは後者によってimportされ、コンパイル、ビューに反映されています

今後チュートリアルをすすめる上でどちらのStylesheetを編集しても問題ないと思いますが
<head>内での呼び出しの順序くらいは気に留めて置いたほうがいいかもしれません

ちなみに、packs内でCSSを編集する場合、webpack-dev-serverのHot reloadの恩恵を受けられます
具体的には、変更保存した場合に自動的にブラウザがリロードされ、即座に(やや遅延あり...)変更内容を確認できます

Railsチュートリアルの流れでcustom.scssを作成する場合
app/javascript/packs/application.jsに以下を記述すれば大丈夫です

import "../stylesheets/custom.scss";

(私はこの仕様で進めてみます)

Troubleshoot

Bootstrapのスタイルがおかしい

おそらくヘッダー周りが上手く表示されないと思います
Bootstrapのバージョンの違いによるものでこちらの記事の通りインストールすると
Bootstrapの最新版ver. 4.5(2020.8.7現在)が導入されます
(Railsチュートリアルでは3.4.1)

navbar-inverseというタグがBootstrap 4では使用できなくなっていますので

  <header class="navbar navbar-expand-md bg-dark navbar-dark bg-dark">

で置き換えるなど細かな修正が必要です
修正を加えたこの章終了時のBranchを公開する予定ですが

yarn addの際にバージョンを指定するといった対策も可能です

テストRSpec関連

assert_...をどう書き換えるか?

そのまま使えます

「RSpecでも assert xxx って書いてテストしたい」=> すぐできます! - Qiita

ApplicationHelperをテストでも使えるように...

include ApplicationHelperを個別の_spec.rbファイルに記述

もしくは、spec/rails_helper.rbに記述
_spec.rbでrequireされているので、個々に記述する必要はないはずです

おわりに

この部分はRails 6環境で個人アプリ開発にあたり、最も苦労しました

身の丈に合わない内容で誤りを含むかもしれませんが

Railsチュートリアルの環境構築だけでなく、Rails 6環境でアプリ開発を行う方の一助になれば幸いです