[Rails6.0] Rails6 + yarn + webpacker でMaterial Design for Bootstrapを導入する

# はじめに

Bootstrapのような使い心地でデザインに変化を付けたくて色々探したら、Material Design for Bootstrapが良さそうだったので導入してみました。

ただ、gem版をインストールする方法やsproketsを利用する方法は見つかったのですが、Rails6標準の`yarn` + `webpacker`での導入方法が見つからなかったので記事にさせていただきました。

# Material Design for Bootstrapとは？

Bootstrapをマテリアルデザインに拡張するテーマです。
Bootstrapに別途でインストールすることで手軽にマテリアルデザインのUIが使えます。

[Material Design for Bootstrap](https://fezvrasta.github.io/bootstrap-material-design/)

# マテリアルデザインとは？

Googleが提唱したデザインの概念です。
現実世界の物質に触れたり操作しているようなUIにすることで、利用者が直感的にわかりやすいインターフェースになるという考え方なんだとか。
僕は全く詳しくないので、詳しく知りたい方は下記のリンクを参考にしてみてください。

[公式ガイドライン](https://material.io/)
https://saruwakakun.com/html-css/material

# 導入手順

それでは早速導入していきましょう。
今回はRailsアプリを新規作成して初期画面 (Yay! You're on Rails!) が表示できたところからスタートです。
Rails6でのアプリの新規作成の方法に関しては、以前記事にしたので参考にしていただければ幸いです。

[[Rails6.0.0][Mac]Rails 6で新しいアプリを作成、サーバー起動して初期画面を表示する](https://qiita.com/sasakura_870/items/44baadd3546eae4554c1)

## スキャフォールド

とりあえず`scaffold`でページの土台を作っていきます。

```bash
$ bin/rails g scaffold Post title:string content:text
$ bin/rails db:migrate
```

`config/routes.rb`を編集してルートを設定します。

```config/routes.rb
Rails.application.routes.draw do
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
  resources :posts
  root 'posts#index'
end
```

## パッケージのインストール

次に`yarn`で必要なパッケージをインストールしましょう。
必要なパッケージは

+ Bootstrap本体の`bootstrap`
+ Material Design for Bootstrapの`bootstrap-material-design`
+ Bootstrapに必要な`jquery`
+ これまたBootstrapに必要な`popper.js`

以上4つです。`yarn add`で一気にインストールしていきます。

```bash
$ yarn add bootstrap bootstrap-material-design jquery popper.js
```

## pack内のapplication.jsの記述

次に`yarn`でインストールしたパッケージを使用するように設定していきます。
`app/javascript/pack/application.js`に以下のコードを追加します。

```app/javascript/pack/application.js
import 'bootstrap-material-design'
import '../stylesheets/application'
```

このファイルはWebブラウザからJavaScriptで読み込ませるためのエントリーファイルになります。

## application.scss作成

先ほどの`application.js`では`../stylesheets/application`を読み込むように記述しました。
なので今からこのファイルを`app/javascript`内に作っていきます。
必要なのは`stylesheets`フォルダと`application.scss`ファイルです。

```bash
$ mkdir app/javascript/stylesheets
$ touch app/javascript/stylesheets/application.scss
```

作成した`application.scss`に以下のコードを追加します。

```scss
@import '~bootstrap-material-design/scss/bootstrap-material-design';
```

あと少しです！

## application.erb.htmlの記述

最後にレイアウトのコードを変更します。
`app/views/layouts/application.erb.html`にこのようなコードがありますが

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

こちらを以下のように変更します。

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

`stylesheet_link_tag`を`stylesheet_pack_tag`に変更しています。

## jQueryとPopper.jsの有効化

**2019/11/1追記 @matt-noteさんありがとうございます！**

Bootstrapは内部で`jQuery`と`Popper.js`というライブラリを使用しています。
このままだとBootstrap内部で動いている`jQuery`と`Popper.js`の変数(`$`とか`jQuery`とか)が定義されておらず、ブラウザのコンソールで`Uncaught ReferenceError: jQuery is not defined`というエラーが出てきます。
なので、この変数を`webpacker`で定義しておきましょう。
`app/config/webpack/environment.js`を以下のコードに変更します。

```app/config/webpack/environment.js
const { environment } = require('@rails/webpacker') 
const webpack = require('webpack') 
 environment.plugins.append('Provide', 
   new webpack.ProvidePlugin({ 
     $: 'jquery', 
     jQuery: 'jquery', 
     Popper: ['popper.js', 'default'] 
   }) 
 ) 

 module.exports = environment
```

**追記ここまで**

以上で準備が整いました。お疲れ様でした。

# 実際に書いていく

例えば`index.html.erb`を以下のように記述すると

```erb
<p id="notice"><%= notice %></p>

<h1>Posts</h1>

<table class="table">
  <thead>
    <tr>
      <th scope="col">Title</th>
      <th scope="col">Context</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @posts.each do |post| %>
      <tr>
        <td scope="row"><%= post.title %></td>
        <td scope="row"><%= post.context %></td>
        <td><%= link_to 'Show', post, class: "btn btn-outline-primary" %></td>
        <td><%= link_to 'Edit', edit_post_path(post), class: "btn btn-raised btn-default" %></td>
        <td><%= link_to 'Destroy', post, class: "btn btn-raised btn-danger", method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<br>

<%= link_to 'New Post', new_post_path, class: 'btn btn-raised btn-primary' %>
```

このように表示されます。

Bootstrap
<img width="1440" alt="スクリーンショット 2019-09-19 17.36.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449905/7c91f66e-ebf4-78f6-a662-5fad0ea5d8b4.png">

Material Design for Bootstrap
<img width="1440" alt="スクリーンショット 2019-09-19 17.35.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449905/a0cec736-f1e8-0793-1977-674b3814e8df.png">

ボタンだけでも結構印象が変わるのではないでしょうか！

# まとめ

長くなりましたが以上で導入は完了です。
Material Design for Bootstrapには様々なコンポーネントがあるので、興味のある方は[公式ドキュメント](https://fezvrasta.github.io/bootstrap-material-design/)を是非ご覧になってください。

何か直すべき点、間違った記述があればコメント等で指摘していただければと思います。