Rails+Vue.js+Vuetify環境の構築手順

自分用メモです。

## 環境
| app        | version |
| ---------- | ------- |
| MacOS      | 10.13.6 |
| yarn       | 1.3.2   |
| vue        | 2.5.17  |
| vue-loader | 15.4.2  |
| Ruby       | 2.4.1   |
| Rails      | 5.2.1   |

## 目次
1. webpackerのHello Worldまで
2. Vue.jsのHello Worldまで
3. Vuetifyの動作確認

## 1. webpackerのHello Worldまで
``webpacker`` の ``Gem`` をインストールする。

```
$ bundle exec rails new rails_vuetify_demo
$ cd rails_vuetify_demo

$ vim Gemfile
gem 'webpacker', github: 'rails/webpacker'
$ bundle install --path vendor/bundle
$ bundle exec rails webpacker:install
```

``top_controller`` を生成して ``root`` として ``application.html.erb`` が表示できるようにする。

```
$ bundle exec rails g controller top --no-assets --no-helper --no-test-framework --skip-routes --skip-template-engine
$ vim app/controllers/top_controller.rb
class TopController < ApplicationController
  def index
    render html: "", layout: true
  end
end

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

``javascript_include_tag`` 行を削除して ``app/javascript/packs/application.js`` を読み込むように修正する。

```
$ vim app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>RailsVuetifyDemo</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application' %> ←追加
  </head>

  <body>
    <%= yield %>
  </body>
</html>
```

ブラウザのconsole上に "Hello World from Webpacker" が出力されていることを確認する。

```
$ bin/webpack
$ bundle exec rails s
$ open http://localhost:3000
```

## 2. vue.jsのHello Worldまで

``webpacker`` のコマンドを使って ``Vue.js`` をインストールする。``vue-loader`` のバージョンを聞かれるので、https://www.npmjs.com/package/vue-loader に書かれている最新版（執筆時点では15.4.2）を選択する。

```
$ bundle exec rails webpacker:install:vue
? Please choose a version of "vue-loader" from this list:
15.4.2

$ cat package.json
{
  "name": "rails_vuetify_demo",
  "private": true,
  "dependencies": {
    "@rails/webpacker": "https://github.com/rails/webpacker",
    "vue": "^2.5.17",
    "vue-loader": "^15.4.2",
    "vue-template-compiler": "^2.5.17"
  },
  "devDependencies": {
    "webpack-dev-server": "^3.1.9"
  }
}
```
``app/javascript/packs/hello_vue.js`` を読み込むように修正する。

```
$ vim app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>RailsVuetifyDemo</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

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

  <body>
    <%= yield %>
  </body>
</html>
```

ブラウザに "Hello Vue!" が表示されていることを確認する。

```
$ bin/webpack
$ bundle exec rails s
$ open http://localhost:3000
```

## 3. Vuetify の動作確認まで

``yarn`` を使って ``Vuetify`` をインストールする。

```
$ yarn add vuetify
$ cat package.json
{
  "name": "rails_vuetify_demo",
  "private": true,
  "dependencies": {
    "@rails/webpacker": "https://github.com/rails/webpacker",
    "vue": "^2.5.17",
    "vue-loader": "^15.4.2",
    "vue-template-compiler": "^2.5.17",
    "vuetify": "^1.2.6"
  },
  "devDependencies": {
    "webpack-dev-server": "^3.1.9"
  }
}
```

``vuetify.min.css`` と ``MaterialIcon`` を使えるように修正する。（とりあえずはCDN経由で読み込む）

```
$ vim app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>RailsVuetifyDemo</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <link href="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.min.css" rel="stylesheet">
    <link href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons' rel="    stylesheet">
    <%= javascript_pack_tag 'hello_vue' %>
  </head>

  <body>
    <%= yield %>
  </body>
</html>
```

``Vue.js`` で ``Vuetify`` を使えるように修正する。

```
$ vim app/javascript/packs/hello_vue.js
/* eslint no-console: 0 */
// Run this example by adding <%= javascript_pack_tag 'hello_vue' %> (and
// <%= stylesheet_pack_tag 'hello_vue' %> if you have styles in your component)
// to the head of your layout file,
// like app/views/layouts/application.html.erb.
// All it does is render <div>Hello Vue</div> at the bottom of the page.

import Vue from 'vue'
import Vuetify from 'vuetify'
import App from '../app.vue'

Vue.use(Vuetify)

document.addEventListener('DOMContentLoaded', () => {
  const el = document.body.appendChild(document.createElement('hello'))
  const app = new Vue({
    el,
    render: h => h(App)
  })

  console.log(app)
})
```

``Vuetify`` の適当なコンポーネントを表示するように ``app.vue`` を修正する。今回は ``MaterialIcon`` の表示確認も行う意味で、 https://vuetifyjs.com/ja/components/alerts にある Alert を表示しています。

```
$ vim app/javascript/app.vue
<template>
  <v-app>
    <p>{{ message }}</p>
    <v-alert
      :value="true"
      type="success"
    >
      This is a success alert.
    </v-alert>
  </v-app>
</template>

<script>
export default {
  data: function () {
    return {
      message: "Hello Vue!"
    }
  }
}
</script>

<style scoped>
p {
  font-size: 2em;
  text-align: center;
}
</style>
```

以下のような表示になれば ``Vuetify`` の動作確認としては問題ないと思います。
<img width="819" alt="スクリーンショット 2018-10-06 16.23.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/25691/c922dbd3-58a9-e770-177c-f85a42e52394.png">

``github`` にもアップしています。
https://github.com/kuni0128/rails_vuetify_demo