SSTエンジニアブログ

SSTのエンジニアによるWebセキュリティの技術を中心としたエンジニアブログです。

夏の宿題「Laravel Mix に挑戦!~Laravel でVue.jsをうごかすまで~」

はじめに

こんにちは。 脆弱性診断業務に携わっています、かをると申します。

この夏、みなさまはどのように過ごされましたか? 先日、弊社の東京オフィスではオフィスツアーが実施され、子どもたちが遊びに来てくれました。

私が子どもの頃の夏休みといえば、だいたい遊び倒しで…プール、虫取り、花火大会、かき氷、スイカ、マンガ、ゲーム…そして終わらない宿題…だと思っていましたが…

子どもたち「宿題やって当然。計画的にやるよ。」

というわけで(?)私も宿題として「LaravelでVue.jsにさわってみる」を自ら設定して、8月の土日や学習時間*1を利用してブログ執筆をしてみました。

宿題「Laravel Mix に挑戦!~Laravel でVue.js うごかすまで~」

ゴールはどこ?

  • (理想)簡単な日記機能の実装とかできたらいいなぁ~
  • (現実)スキルと時間考えてHelloWorld相当 👈 こっち

なぜこのテーマ?

  1. SSTエンジニアブログの1回目でVue.jsの記事を見た
  2. 新人研修*2で触れたLaravelをもっと知りたいと思っていた
  3. 「Laravel Vue.js」で検索すると、最初から入ってる?的な記載 👈 いいね!※😇 *3

やったこと

  1. Laravel導入
  2. Vue.jsのための設定(Laravel Mix ※😇 *4
  3. サンプルのComponentを表示する
  4. オリジナルのComponentを表示する

0. 環境について

  • macOS High Sierra 10.13.6 *5
  • Virtual Box 5.1.28
  • Vagrant 2.1.2
    • laravel/homestead (virtualbox用, 6.1.0)

1. Laravel導入

Laravelを利用できるまでの設定もいろいろと実施したのですが、ブログが長くなってしまうのでさらっと書きます。 Laravelのサーバ要件を満たす環境を作成するために、Laravel Homesteadという公式のパッケージ化されたVagrant Boxを利用しました。 また、プロジェクトを作成は、Laravel Homestead上でComposerを利用しました。(プロジェクト名はLaravelにしています。)

また、Homestead環境の設定ファイルHomestead.yamlにて、ホスト名をHomestead.appに設定しています*6

バージョンは Laravel Framework 5.6.33、プロジェクトのディレクトリ構成と、本記事に出てくるファイルは以下のように配置しました。

Laravel(プロジェクト名)/
 ├ app/
 ├ bootstrap/
 ├ config/  
 ├ database/
 ├ public/
 ├ resources/
 │ ├  assets/
 │ │    └ js/
 │ │        └ components/
 │ │           ├ ExampleComponent.vue
 │ │           └ ORiginalComponent.vue
 │ └ views 
 │   └ vuesample.blade.php
 ├ routes/
 │ └ web.php
 ├ storage/
 ├ tests/
 ├ artisan
 ├ composer.json
 ├ package.json
 ├ phpunit.xml
 ├ readme.md
 ├ server.php
 └ webpack.mix.js

2. Vue.jsのための設定 ( Laravel Mix ※😇 )

当初は、Laravelの設定が終了すれば動作するだろうと気楽に考えていましたが、「新人研修のときに学習コスト高そう」と避けた*7Laravel Mixを使うことがわかりました 😇

Laravel Mix について*8

Laravel Mixは多くの一般的なCSSとJavaScriptのプリプロセッサを使用し、Laravelアプリケーションために、構築過程をWebpackでスラスラと定義できるAPIを提供しています。*9

…ドキュメントがしっかりしているので、きっとなんとかなる😇。 というわけで、いよいよLaravvel Mixに挑戦です!

Node.jsとnpmのインストール

Laravel Mixを使うにあたり、マストなのがこの2つ。私はLaravel Homesteadを利用していたので、デフォルトのまま利用*10しました。

  • node: v8.11.2
  • npm: 6.1.0
Laravel Mixのインストール

npm install コマンド*11でLaravel Mixをインストールしました。 コマンドを実行すると、package.json 中の devDependencies のパッケージがインストールされます。laravel-mixの記載もありました👀

/package.json

{
   "private": true,
        "dev": "npm run development",
         "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
        "watch": "npm run development -- --watch",
        "watch-poll": "npm run watch -- --watch-poll",
       "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
       "prod": "npm run production",
       "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
   },
   "devDependencies": {
       "axios": "^0.18",
       "bootstrap": "^4.0.0",
       "popper.js": "^1.12",
       "cross-env": "^5.1",
       "jquery": "^3.2",
       "laravel-mix": "^2.0",
       "lodash": "^4.17.4",
       "vue": "^2.5.7"
   }
}

3. サンプルのComponentを表示する

ルーティングの設定 *12

どういうリクエストのときに、どのビューが表示されるかの設定を行います。まずは、デフォルトのビューではなく、自分で作成したビューが表示されるように設定します。

/routes/web.php

<?php

Route::get('/', function () {
    
    //初期設定のViewページへ
    //return view('welcome');
    
    //自分で作成したviewのページ(vuesample.blade.php)へ
     return view('vuesample');
});
コンポーネントの作成

まずはサンプルのコンポーネントを表示してみようとおもうので、特に編集せずそのまま読み込みます。 画面に「I'm an example component」、コンソールに「Component mounted.」と表示してくれるものです。

/resources/assets/js/components/ExampleComponent.vue

<template>
   <div class="container">
       <div class="row justify-content-center">
           <div class="col-md-8">
               <div class="card card-default">
                   <div class="card-header">Example Component</div>

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

<script>
   export default {

       mounted() {
           console.log('Component mounted.')
       }
   }
</script>
ビューの作成 *13

サンプルのコンポートが表示されるように、ビューを作成します。*14

/resources/views/vuesample.blade.php

<!DOCTYPE html>
<html lang="{{ config('app.locale')}}">
 <head>
   <meta charset="utf-8">
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <meta name="csrf-token" content="{{ csrf_token() }}">

   <title>Laravel Mix に挑戦! 〜LaravelでVue.jsをうごかすまで〜</title>

   <link rel="stylesheet" href="{{ mix('css/app.css') }}">

 </head>

 <body>
     <div id="app">
         <!--デフォルトでappの要素中でvue.jsが有効になっている-->
         <example-component></example-component>

     </div>

 <!--vue.jsのコンポートなどをロードするので、app.jsは全てのコンポートのあとに追加する。-->
 <script src="{{ mix('js/app.js') }}" ></script>
 </body>

</html>
Laravel Mix始動(アセットのコンパイル)

いよいよlaravel Mix✨アセットのコンパイルには、魔法の呪文 npm run dev を唱えます。

これで、package.json 中の"development"のスクリプトが実行され、イイカンジにしてくれます。

"dev": "npm run development",
     "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",

アセットは以下。Vueのインスタンスはこのタイミングで作成されている…のかな…?

/resources/assets/js/app.js

// このプロジェクト全てのJavaScriptの依存関係が読み込まむ(Vueや他のライブラリも)
require('./bootstrap');
window.Vue = require('vue');

// 新しくVueのインスタンスを作成&ページに追加
// ビューに記載の<example-component></example-component>コンポーネントはここで作られてる
Vue.component('example-component', require('./components/ExampleComponent.vue'));

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

結果はCompiled Successfully!😊 f:id:kaworu-san:20180831140115p:plain

結果

さっそくhttp://Homestead.app/にアクセスして確認してみます。

サンプルのコンポーネントが表示されました😍 f:id:kaworu-san:20180831163454p:plain

4. オリジナルのComponentを表示する

作業内容
  • vuesample.blade.phpを修正
  • app.js を修正
  • OriginalComponent.vueを新規作成

そして最後に npm run dev

/resources/views/vuesample.blade.php

<!DOCTYPE html>
<html lang="{{ config('app.locale')}}">
 <head>
   <meta charset="utf-8">
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <meta name="csrf-token" content="{{ csrf_token() }}">

   <title>Laravel Mix に挑戦! 〜LaravelでVue.jsをうごかすまで〜</title>

   <link rel="stylesheet" href="{{ mix('css/app.css') }}">

 </head>

 <body>
     <div id="app">
         <example-component></example-component>
     </div>

     <!--追加したオリジナルのコンポーネント-->
     <div id='compdemo'>
       <original-component></original-component>
     </div>

 <script src="{{ mix('js/app.js') }}" ></script>
 </body>

</html>

/resources/assets/js/app.js

require('./bootstrap');
window.Vue = require('vue');

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

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

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

OriginalComponent.vue

<template>
   <div class="container">
       <strong>Success!</strong> {{ body }}
   </div>
</template>

<script>
   export default {

       data() {
           return {
               body: 'Hello World!'
           }
       },
       name:'original-component'
   }
</script>
結果

再度、ビューを見に行くと、先ほど作成したコンポーネントが表示されています😍😍😍 HelloWorld(見辛くてごめんなさい)達成〜なんとかゴール🏁です! f:id:kaworu-san:20180831173413p:plain

おわりに

ここまであっさり記載しましたが、自分的にじつはいろいろな沼にはまっていました。 時間を特に溶かした2つを紹介します。

npm run developmentのスクリプトで呼ばれている webpack.jswebpack.config.js をみてみた

webpack.mix.js ファイルは全アセットコンパイルのエントリポイントです。Webpackの軽い設定ラッパーだと考えてください。Mixタスクはアセットをどのようにコンパイルすべきかを正確に定義するため、チェーンでつなげます。*15

この記述をみて、npm run development で実行されるスクリプトに webpack.mix.js が書かれているのかな?と考えました。しかし、そこに記載はありませんでした。そこでスクリプトに記載のある webpack.jswebpack.config.js の内容を見てみました。 「こういう風に利用されています」とかブログに書きたかったのですが理解及ばず…。 f:id:kaworu-san:20180831175419j:plain わかる方にぜひ教えて頂きたいです🙇

コンポーネントが表示されない??

本記事に記載したもの以外にも、vue.jsのコンポーネントを作成してみました。ところがエラーも出ないのになぜか描画されない…?ということがありました。こちらは「スーパーリロード」で更新して解決したのですが、地味に時間をとかしたのでここで供養します…

それでは、私の夏の宿題につきあってくださり、ありがとうございました!

今回の記事は私の見解に基づくものであり、所属組織を代表するものではありません。 また、できるだけ正確に記載するよう努めましたが、至らない点ばかりかと思います。宿題ですので、どうぞみなさま赤ペン先生💯💮となって教えてください。

ぜーんぜんぜんぜん終わらない、ひたすら書きまくった、8月最終日のブログでした🐊💭*16

注釈一覧

*1:SSTではスキルアップの一環として、業務時間中に興味のある内容を学習できる制度があります。

*2:私は2017年に新卒としてSSTへ入社しました。新人研修の一環で「1か月半程度・自由なテーマでモノづくり」があり、私はフレームワークに触れるというテーマで初心者向けタスクリストを作成しました。また、MVCに分けたり、自分で機能を追加するということを実施しました。

*3:楽をしようとしたら、結果として学習することが多い落とし穴😇

*4:楽をしようとしたら、以下略😇

*5:私物のMacBook Pro💻を利用しました

*6:Readouble-LaravelHomesteadLaravel学習帳 を参考にしました

*7:私が初めてフレームワークに触れたのが新人研修で、できるだけ新しい要素を排除して学習したかったのでLaravel Mixは避けました。

*8:Laravel MixドキュメントLaravel MixのGithub

*9:Readouble-Laravel Mix

*10:調べていく中で、インストール時のバージョン等によってうまく行かない場合も散見しました。もし詰まってしまった場合は、少し調べてみてください。

*11:npm install は npm run dev のように引数は必要ないのだろうか?という疑問があり、あざらし先輩にnpm installコマンドについてきちんと教えてもらいました。

*12:ルーティングはLaravelの担当。Laravel ドキュメント-Routing

*13:View自体はLaravelの担当。Laravelドキュメント-Views

*14:参考: LaravelからVue.jsを使う最短レシピ

*15:Readouble-アセットのコンパイルより引用

*16:今回の作業用BGM。酸素をつくるには?「xxとxxxxx!」