npm
laravel
docker
vue.js
laravel5

Laradockを使った開発環境でVueを動かすまで

目的

Laradockを使った開発環境で、Vueを動かすまでを解説します。
LaravelでRestAPIを作り、Vueでビューを実装する前提です。
npmを使うので、Docker上でnodejsやnpmインストールをするところから解説します!

免責 2017年12月18日現在

Laravel-mix(webpack)が生成するapp.jsの更新前ファイルがうまく消えずに、エラーとなります。
結果的に、"npm run watch"が使えません…(かなり悲しい)
無理矢理な方法で"npm run dev"は実行可能です。
解決次第、記事を更新します。

Laradock(Dockerイメージ群)のインストール

こちらを参照してください。

手順

  1. nodejsインストール
  2. npmインストール
  3. welcome.blade.phpを変更
  4. ExampleComponent.vueを変更
  5. npm run devを実行
  6. \u0問題
  7. 補足 welcome.blade.jsとExampleComponent.vueの関連性

1. nodejsインストール

ローカルでnodejsとnpmをインストールして動作しそうですが、「\u0問題」があったので、Docker上でnpmを実行します。

Laradockで構築している場合、workspaceコンテナに入ります。

コンテナにログイン
$ docker-compose exec workspace bash

apt-get install -y だけだとうまくいかないっぽい
参考

nodejsインストール
root@{コンテナ名}:/var/www# curl -sL https://deb.nodesource.com/setup_8.x | bash -
root@{コンテナ名}:/var/www# apt-get install -y nodejs

2. npmインストール

最新版をインストールします。

npmインストール
root@{コンテナ名}:/var/www# npm install npm@latest -g]

3. welcome.blade.phpを変更

Laradockで環境構築後
http://192.168.99.100/
にアクセスすると、「Laravel」と表示されます。

Laravel.PNG

この画面は"welcome.blade.php"を表示しています(詳しい説明は省略します)。
この"welcome.blade.php"を次のように変更します。

"welcome.blade.php"は、"/src/resources/views/"にあります・

/src/resources/views/welcome.blade.php
<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Hello Vue</title>
    <link rel="stylesheet" href="css/app.css"/>
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <script type="text/javascript">
        window.Laravel = window.Laravel || {};
        window.Laravel.csrfToken = "{{csrf_token()}}";
    </script>
</head>
<body>
<div id="app">
    <example-component></example-component>
</div>
<script src="js/app.js"></script>
</body>
</html>

このソースの

の部分が、vueファイルを呼んでいます。

Laravel-mix実行
$ docker-compose exec workspace npm run dev

> @ dev /var/www
> npm run development


> @ development /var/www
> cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js

 95% emitting

 DONE  Compiled successfully in 6233ms                                                                        6:39:43 AM
                                                                                                                                                                                                               Asset     Size  Chunks                    Chunk Names
  fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.eot?f4769f9bdb7466be65088239c12046d1  20.1 kB          [emitted]
fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.woff2?448c34a56d699c29117adc64c43affeb    18 kB          [emitted]
 fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.woff?fa2772327f55d8198301fdb8bcfc8158  23.4 kB          [emitted]
  fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.ttf?e18bbf611f2a2e43afc071aa2f4e1512  45.4 kB          [emitted]
  fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.svg?89889688147bd7575d6327160d64e760   109 kB          [emitted]
                                                                                               /js/app.js  1.23 MB       0  [emitted]  [big]  /js/app
                                                                                             /css/app.css   147 kB       0  [emitted]         /js/app

上記のような表示が出れば成功です。

http://192.168.99.100/
にアクセスすると次のような画面になります。

vue.PNG

4. ExampleComponent.vueを変更

ExampleComponent.vueの文言を変更します。

変更後の/src/resources/assets/js/components/ExampleComponent.vue
<template>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <div class="panel panel-default">
                    <div class="panel-heading">コンポーネントの実験</div>

                    <div class="panel-body">
                        こんなかんじ?
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        mounted() {
            console.log('Component mounted.')
        }
    }
</script>

5. npm run devを実行

npm run devを実行し、Laravel-mixでデプロイ(?)します。

Laravel-mixでデプロイ(面倒)
$ docker-compose exec workspace rm public/js/app.js && docker-compose exec workspace npm run dev

すると、次のような画面になります。

vue変更後.PNG

6. \u0問題

本来であれば
bash:本来
$ npm run dev

でいいはずですが、次のようなコマンドを実行します。

悲しい現実
$ docker-compose exec workspace rm public/js/app.js && docker-compose exec workspace npm run dev

原因は調査中ですが、「Docker上で」"/src/public/js/app.js"を削除してから、npm run devを実行する必要があります。
これをワンライナーで表現すると、上記コマンドになります。

問題1

「Docker上で」"/src/public/js/app.js"を削除しないと、キャッシュが消えてくれません。

問題2

下記だけ実行すると、前のapp.jsに\u0が追加され、JavaScriptエラーとなります…

本来
$ npm run dev

Developerツールで見た画面

JSエラー.PNG

画像の赤丸が「\u0」です。
試行錯誤の結果、「Docker上で」一回削除してから、npm run devを実行すると、この問題が起きません。

問題3

ローカルでファイル削除→npm run dev実行すると、キャッシュが残る???
結果うまくいかない…

自動的に変更を検知するwatchモードがつかなくて困っています…

補足 welcome.blade.jsとExampleComponent.vueの関連性

vueファイルは"/src/resources/assets/js/components/"にあります。

/src/resources/assets/js/components/ExampleComponent.vue
<template>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <div class="panel panel-default">
                    <div class="panel-heading">Example Component</div>

                    <div class="panel-body">
                        I'm an example component!
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        mounted() {
            console.log('Component mounted.')
        }
    }
</script>

このvueファイルと"welcome.blade.php"を関連付けているのが、"/src/resources/assets/js/app.js/"です。

/src/resources/assets/js/app.js/
/**
 * First we will load all of this project's JavaScript dependencies which
 * includes Vue and other libraries. It is a great starting point when
 * building robust, powerful web applications using Vue and Laravel.
 */

require('./bootstrap');

window.Vue = require('vue');

/**
 * Next, we will create a fresh Vue application instance and attach it to
 * the page. Then, you may begin adding components to this application
 * or customize the JavaScript scaffolding to fit your unique needs.
 */

Vue.component('example-component', require('./components/ExampleComponent.vue'));

const app = new Vue({
    el: '#app'
});

下記が、"welcome.blade.php"の""と"ExampleComponent.vue"を関連付けしています。
Vue.component('example-component', require('./components/ExampleComponent.vue'));