Webpacker で Bootswatch (Bootstrap v4) + Vue.js の Rails プロジェクトを作成する

# この記事は

まだ [Webpacker](https://github.com/rails/webpacker) を使ったことがなかったので、今回 Webpacker で Vue.js を使った Rails プロジェクトを作成し、さらに [Bootstrap](https://getbootstrap.com/) および [Bootswatch](https://bootswatch.com/) の任意のテーマを導入するところまで試してみました。

# 手順

Rails プロジェクトのディレクトリを作成します。この例では `hidamarisou` にします。

```
$ mkdir hidamarisou
$ cd hidamarisou
```

`Gemfile` を作成します。

```rb:Gemfile
source 'https://rubygems.org'

gem 'rails'
gem 'webpacker'
```

`bundle install` します。

```
$ bundle install --path vendor/bundle
```

`rails new` します。ターミナルで選択肢を訊かれたらすべて `Y` を選択します。

```
$ bundle exec rails new . --webpack=vue
```

Bootstrap と Bootswatch のパッケージをインストールします。

```
$ yarn add bootstrap bootswatch
```

Bootstrap の JavaScript ファイルを読み込みます。

```diff:app/javascript/packs/application.js
-console.log('Hello World from Webpacker')
+import 'bootstrap/dist/js/bootstrap';
```

Bootstrap と Bootswatch の Sass ファイルを読み込みます。なお、この例では Bootswatch のテーマに [Journal](https://bootswatch.com/journal/) を使用します。読み込み順に注意してください。

```app/javascript/packs/application.scss
@import '~bootswatch/dist/journal/variables';
@import '~bootstrap/scss/bootstrap';
@import '~bootswatch/dist/journal/bootswatch';
```

Bootstrap の JavaScript が動作するように Webpack の設定を更新します。

```diff:config/webpack/environment.js
const { environment } = require('@rails/webpacker')
const vue =  require('./loaders/vue')
+const webpack = require('webpack')

environment.loaders.append('vue', vue)
+environment.plugins.set('Provide', new webpack.ProvidePlugin({
+  $: 'jquery',
+  jQuery: 'jquery',
+  Popper: ['popper.js', 'default']
+}))
+
```

`app/views/layouts/application.html.erb` で `app/javascript/packs/application.js` と `app/javascript/packs/application.scss` を読み込みます。

```diff: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' %>
</head>

<body>
```

Vue.js の動作を確認するために、試しにコントローラを作成します。

```
$ bin/rails g controller Page home
```

生成された `app/views/page/home.html.erb` で `app/javascript/packs/hello_vue.js` を読み込みます。最初 `javascript_pack_tag` だけで Vue ファイル内の CSS も効くものだと思っていましたが、実際は `stylesheet_pack_tag` も必要でした。

```diff:app/views/page/home.html.erb
-<h1>Page#home</h1>
-<p>Find me in app/views/page/home.html.erb</p>
+<%= javascript_pack_tag 'hello_vue' %>
+<%= stylesheet_pack_tag 'hello_vue' %>
```

Rails サーバを起動し http://localhost:3000/ にアクセスします。

```
$ bin/rails s
```

![ss01.png](https://qiita-image-store.s3.amazonaws.com/0/6697/a0137d08-97b1-fcda-8a2c-79ebb2f4c732.png)

`app/javascript/app.vue` が動いているようです :tada:

ただし、これでは Bootswatch が正しく導入されているか分かりません。そこで `app/javascript/app.vue` を次のように書き換えます。

```html:app/javascript/app.vue
<template>
  <div id="app">
    <nav class="navbar fixed-top navbar-expand-lg navbar-dark bg-primary">
      <a class="navbar-brand" href="#">Hidamarisou</a>
    </nav>
    <main role="main" class="container">
      <div class="jumbotron">
        <h1>ひだまり荘</h1>
        <p class="lead">{{ message }}</p>
        <button class="btn btn-outline-primary" type="submit">入る</button>
      </div>
    </main>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: '✘╹◡╹✘ ようこそひだまり荘へ ✨'
    };
  }
};
</script>

<style scoped>
#app {
  padding-top: 5.0rem;
}
</style>
```

![ss02.png](https://qiita-image-store.s3.amazonaws.com/0/6697/1a880af6-9578-a401-dded-9ef960d75aff.png)

これで Bootswatch のテーマが正しく効いていることも確認できました :tada:

# 参考

* [Rails 5.1 + Vue.js で開発を行う - part1 環境構築](https://qiita.com/cohki0305/items/582c0f5ed0750e60c951)
* [rails/webpacker » Issue #987 » Webpacker:Vue component styles do not work](https://github.com/rails/webpacker/issues/987)