Rails 5.1 + Vue.js で開発を行う - part1 環境構築


# 概要

- Webpacker を利用してRails 5.1 + Vue.js で開発を行う方法を紹介。
- 本記事では、開発環境を整えるまで行う
	- 次回の記事では、Vue.js を使って Ajax 通信を行います。
	- [Rails 5.1 + Vue.js で開発を行う - part2 Ajax で GET しよう！](http://qiita.com/cohki0305/items/a678b0b17c5b496c1de9)から確認ください
- 全コードは[こちら](https://github.com/cohki0305/webpacker-and-vue)より確認いただけます


# 環境

- ruby 2.4.1
- Rails 5.1.1
- Vue 2.3.4

# webpacker のインストール

はじめに webpacker を install します。
※ Rails アプリをすでに作成済みという前提で話を進めます。

webpacker とは

> Webpacker makes it easy to use the JavaScript pre-processor and bundler Webpack 2.x.x+ to manage application-like JavaScript in Rails.

Ref. [Rails/webpacker | Github](https://github.com/rails/webpacker)

## gem 'webpacker' をインストール

Gemfile を以下のように編集して、インストールします


```ruby:Gemfile

gem 'webpacker', github: 'rails/webpacker'

```

```
$ bundle install
```

**備考**
Rails アプリを初めて作成する場合は、以下で webpack と Vue.js のインストールが可能です。

```
$ rails new myapp --webpack=vue
```

詳細は公式ドキュメントをご確認ください。
[Rails/webpacker | Github](https://github.com/rails/webpacker)

## yarn のインストール

インストールされている場合は必要ありません。
インストールしていない場合は以下のコマンドを実行してください。

```
$ brew install yarn

# インストールされているか確認
$ yarn -v
yarn install v0.23.2
```

**備考**


brew が入っていない人は以下を参考にしてインストールしてください。
[Homebrew macOS 用パッケージマネージャー](https://brew.sh/index_ja.html)

## webpacker のインストール

以下のコマンドで webpacker をインストールしてください。
webpack 関連のファイルが作成・更新されます。

```
$ rails webpacker:install 
# Webpacker successfully installed 🎉 🍰
```

# Vue.js のインストール

```
$ rails webpacker:install:vue
```

vue がインストールされて、`app/javascript/packs` 配下にファイルが作成されたことが確認できると思います。

# Rails アプリ上で Vue.js を利用する

## Root ページを作成

```
$ rails g controller Page home
```

```ruby:routes.rb
Rails.application.routes.draw do
  root to: 'page#home'
end
```

## Vue.js を Rails View で読み込む

`javascript_pack_tag` で `app/javascript/packs` 配下にあるファイルを読み込むことができます。
Sprockets とは異なり、必要なファイルを必要な `View` で読み込むことができるので、JS の思わぬ挙動に苦しめられることはあまりないかと思います。

```html:app/views/page/home.html.haml

%h1 Page
= javascript_pack_tag 'hello_vue'

```

```js:app/javascript/packs/hello_vue.js
import Vue from 'vue'
import App from './app.vue'

document.addEventListener('DOMContentLoaded', () => {
  document.body.appendChild(document.createElement('hello'))
  const app = new Vue(App).$mount('hello')

  console.log(app)
})

```

**備考**

hello_vue.js には `layout` の `head` に `javascript_pack_tag` を読み込むように書いているのですが、これだとなぜか動きません。
なので、上では `View` の最後で読み込むようにしています。

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

// Run this example by adding <%= javascript_pack_tag 'hello_vue' %> and
// <%= stylesheet_pack_tag 'hello_vue' %> 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.
```


## JS ファイルのコンパイル

JS のファイルをコンパイルすることで `hello_vue` を開発環境に反映させることができます。
以下のコマンドでコンパイルが完了します。ファイルに変更点があった場合も自動でコンパイルしてくれます。

```
$ bin/webpack-dev-server
```

以下のエラーが生じた場合は webpack-dev-server のバージョンを下げましょう。

```
TypeError: Cannot read property 'compile' of undefined
```

webpacke が 3 系の場合 webpack-dev-server は 2 系である必要があるので以下を実行しましょう。

```
$ yarn add webpack-dev-server@2.11.1 --dev
```

ref. [TypeError: Cannot read property 'compile' of undefined - Github](https://github.com/webpack/webpack-dev-server/issues/1334)

そして `http://localhost:3000/` を確認すると以下のような画面になっているかと思います。
![スクリーンショット 2017-06-18 17.12.13.png](https://qiita-image-store.s3.amazonaws.com/0/100997/e0a8255a-2eaf-8e8c-3954-5d46c7e29b20.png "スクリーンショット 2017-06-18 17.12.13.png")


# Rails の View を操作する


今まで見てきたのはあくまで、`app.vue` を表示しているものにすぎなかった。
ただ、SPA を作るわけでもない限り、一般的には Rails の View を操作することが多いと思われる。
その利用方法をすこし紹介する。

Rails の View つまり html を Vue.js で操作するには、`hello_vue.js` に記述されているように、以下のように変更しなければならない。

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

- import Vue from 'vue'
- import App from './app.vue'

- document.addEventListener('DOMContentLoaded', () => {
-   document.body.appendChild(document.createElement('hello'))
-   const app = new Vue(App).$mount('hello')

-   console.log(app)
- })

+ import Vue from 'vue/dist/vue.esm'

+ const app = new Vue({
+    el: '#hello',
+    data: {
+      message: "Can you say hello?"
+    }
+ })
```


```diff:app/views/page/home.html.haml

- %h1 Page
+ #hello
+   %h1 Page
+   %p {{ message }}
= javascript_pack_tag 'hello_vue'

```

以下のように表示されているはず

![スクリーンショット 2017-06-18 17.27.21.png](https://qiita-image-store.s3.amazonaws.com/0/100997/1c7dd241-b79b-5f85-8515-80857b55de84.png "スクリーンショット 2017-06-18 17.27.21.png")


## ポイント

html を操作する場合は、`vue` ではなくて `vue/dist/vue.esm` を　import する必要がある。

```diff

- import Vue from 'vue'
+ import Vue from 'vue/dist/vue.esm'

```

#　続き

続きは以下の記事で紹介しています。

[Rails 5.1 + Vue.js で開発を行う - part2 Ajax で GET しよう！](http://qiita.com/cohki0305/items/a678b0b17c5b496c1de9)