既存のRailsアプリ(6系)にVue.jsを導入する方法 

#はじめに
この記事は既存のrails6系にvue.jsを導入するものになります。
初学者のアウトプット記事のため間違っているところなどがあるかもしれないですが、よろしくお願いします。
もし間違っているところなどがあったら、随時編集をしていきます。
#Vue.jsの導入
今回は**Webpacker**を用いて導入していきます。

まず既存のrailsアプリケーションの内のディレクトリで、Webpackerを用いてVue.jsをインストールします。WebpackerとはRailsアプリケーションにWebpackをいい感じに取り込めるgemです。Rails6系にはすでに導入されています。

コンソールに以下のコードを打ち込んでください。

```
% bundle exec rails webpacker:install:vue
```
読み込んだら、以下のファイルが存在しているはずです。

``app/javascript/packs/hello_vue.js``

`app/javascript/app.vue`

まず`hello_vue.js`ファイルの中身をみてみましょう。

```javascript
/* 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 App from '../app.vue'


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

  console.log(app)
})


// The above code uses Vue without the compiler, which means you cannot
// use Vue to target elements in your existing html templates. You would
// need to always use single file components.
// To be able to target elements in your existing html/erb templates,
// comment out the above code and uncomment the below
// Add <%= javascript_pack_tag 'hello_vue' %> to your layout
// Then add this markup to your html template:
//
// <div id='hello'>
//   {{message}}
//   <app></app>
// </div>


//import Vue from 'vue/dist/vue.esm'
//import App from '../app.vue'
//
//document.addEventListener('DOMContentLoaded', () => {
  //const app = new Vue({
    //el: '#hello',
    //data: {
      //message: "Can you say hello?"
    //},
    //components: { App }
  //})
//})
//
//
//
// If the project is using turbolinks, install 'vue-turbolinks':
//
// yarn add vue-turbolinks
//
// Then uncomment the code block below:
//
// import TurbolinksAdapter from 'vue-turbolinks'
// import Vue from 'vue/dist/vue.esm'
// import App from '../app.vue'
//
// Vue.use(TurbolinksAdapter)
//
// document.addEventListener('turbolinks:load', () => {
//   const app = new Vue({
//     el: '#hello',
//     data: () => {
//       return {
//         message: "Can you say hello?"
//       }
//     },
//     components: { App }
//   })
// })
```
たくさんのコードがコメントアウトされています。まずはこちらのページの上部の英文から読んでみましょう。

```javascript
// 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.
```
要約するとこんな感じになります。

- 直下のコードを実行する場合は、<%=javascript_pack_tag'hello_vue' %>をhtmlのheadタグに入れること。
- もしあなたがコンポーネントにスタイルを当てている場合は、<%= stylesheet_pack_tag 'hello_vue' %> をheadタグに入れること。
- そうすればページの最下部に"Hello Vue"がレンダリングされる。

言われた通り、`app/views/layouts/application.html.erb`内に以下のコードを追加します。
 
```html
<%= javascript_pack_tag 'hello_vue' %>
<%= stylesheet_pack_tag 'hello_vue'  %> 
```
記述をし終えたら、コンソールで`rails s`を打ち込み確認してみましょう。

![hello vue.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1048562/e30c8a58-3c4e-1475-4d63-c6a6cf1254de.png)
既存のアプリケーションのビューの下に`Hello Vue!`が表示されているはずです。

次は `hello_vue.js`の次の英文を読んでいきましょう。

```javascript
// The above code uses Vue without the compiler, which means you cannot
// use Vue to target elements in your existing html templates. You would
// need to always use single file components.
// To be able to target elements in your existing html/erb templates,
// comment out the above code and uncomment the below
// Add <%= javascript_pack_tag 'hello_vue' %> to your layout
// Then add this markup to your html template:
```
この英文を要約すると

- 上のコードはコンパイルせずにVueを使う場合に使用するもので、`html.erb`の特定の箇所に限定して使うことができず、常にシングルファイルコンポーネントとして使わなければならない。
- `html.erb`の特定の箇所に使いたい場合は、上のコードをコメントアウトして下記のコードを使用する。

要するにhtml.erbの特定の箇所のみにvue.jsを使いたい場合は、この文の下のコードを使う必要があるということですね。言われた通り上のコードをコメントアウトして、下のコードを使用していきましょう。

```javascript
/* 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 App from '../app.vue'


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

//  console.log(app)
//})


// The above code uses Vue without the compiler, which means you cannot
// use Vue to target elements in your existing html templates. You would
// need to always use single file components.
// To be able to target elements in your existing html/erb templates,
// comment out the above code and uncomment the below
// Add <%= javascript_pack_tag 'hello_vue' %> to your layout
// Then add this markup to your html template:
//
// <div id='hello'>
//   {{message}}
//   <app></app>
// </div>


import Vue from 'vue/dist/vue.esm'
import App from '../app.vue'

document.addEventListener('DOMContentLoaded', () => {
  const app = new Vue({
    el: '#hello',
    data: {
      message: "Can you say hello?"
    },
    components: { App }
  })
})



// If the project is using turbolinks, install 'vue-turbolinks':
//
// yarn add vue-turbolinks
//
// Then uncomment the code block below:
//
// import TurbolinksAdapter from 'vue-turbolinks'
// import Vue from 'vue/dist/vue.esm'
// import App from '../app.vue'
//
// Vue.use(TurbolinksAdapter)
//
// document.addEventListener('turbolinks:load', () => {
//   const app = new Vue({
//     el: '#hello',
//     data: () => {
//       return {
//         message: "Can you say hello?"
//       }
//     },
//     components: { App }
//   })
// })
```
そして`html.erb`の任意の箇所に

```html
 <div id='hello'>
   {{message}}
 </div>
```
と記述してみましょう。その任意の箇所に`Can you say hello?`が表示されているはずです。
これらを見てわかった通り、`hello_vue.js`はrailsとvue.jsの橋渡し的な存在になります。VueCLIでいう`main.js`と同じ役割です。

それならばapp.vueはどうでしょうか。確認してみましょう。

```javascript
<template>
  <div id="app"> 
   <p>{{ message }}</p>
  </div>
</template>

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

<style scoped>
p {
  font-size: 2em;
  text-align: center;
}
</style>
```
先ほどの`Hello Vue!`はここのファイルの記述だったということがわかりました。このファイルにVueの記述をしていきます。

以上がVue.jsの導入になります。

# Foremanの導入
これまで`rails s`をターミナルに打ち込んでrailsのサーバーを立ち上げてvueファイルの確認をしてきました。その場合、Vueファイルを変更したら一々リロードをしなければなりません。

そういった時、webpackサーバーを別に立てておくことでJSファイルのコンパイル時間を短縮でき，JSファイルの変更にも自動でリロードできるようになります。

しかしrailsのサーバーとWebpackerのサーバーを立ち上げる必要があり、面倒です。そんな時に便利なのが、Foremanです。Foremanを使えば、この二つのコマンドを一つにまとめてくれます。

```
% gem install foreman
```
このようにgemをインストールして、プロジェクトディレクトリ配下にProcfileというファイルを作成します。そのファイルの中に以下のように記述しましょう。

```
rails: rails s
webpack: ./bin/webpack-dev-server
```
正しく設定できているかどうか以下のコマンドを打って確認してみましょう。

```
foreman check
```
`valid procfile detected (rails, webpack)`
と表示されれば、成功です。

以下のコマンドでrailsのサーバーとwebpackerのサーバーを同時に起動させることができます。

```
% foreman start
```
ポート番号を指定したい場合はこのように指定します。

```
% foreman start -p 3000
```