Laravel5.8+vue.js環境でのHot Module Replacementの設定手順について説明しています。

HMRについて

HMRはHot Module Replacementの略で、Hot Reloadingとも呼ばれます。エディターでコードを更新すると即座にブラウザに更新を反映することができるため、更新の度にページをリロードする必要がなくなります。

Laravel-mixのドキュメントの説明をそのまま日本語訳と一緒に記載しておきます。

Hot Module Replacement (or Hot Reloading) allows you to, not just refresh the page when a piece of JavaScript is changed, but it will also maintain the current state of the component in the browser. As an example, consider a simple counter component. When you press a button, the count goes up. Imagine that you click this button a number of times, and then update the component file. Once you do, the webpage will refresh to reflect your change, but the count will remain the same. It won’t reset. This is the beauty of hot reloading!

Hot Module Replacement(or Hot Reloding)はJavaScriptを変更したときにページをリフレッシュするだけではなくコンポーネントの現在のステータスも保持することができます。例えばカウンターのシンプルな例ですが、ボタンをクリックするとカウンターがアップするものがあります。ボタンを何度もクリックしてカウンターの数字が増えてあとにコンポーネントファイルを更新するとします。ウェブページにはファイルの更新が反映させますが、カウントの値はそのまま保持されます。カウントがリセットされることはありません。これがHot Reloadingの機能です。

環境の構築

MACを使用してLaravel+vue.jsの環境を構築します。HMRの設定が本文書の重要な箇所なので、環境構築についての細かな説明は行っていません。

composerでLaravelのインストール

Laravelのインストールを行います。


$ composer create-project --prefer-dist laravel/laravel hot-reload-test

バージョンを確認し、開発のローカルサーバを起動します。


$ cd hot-reload-test/
hot-reload-test $ php artisan -V
Laravel Framework 5.8.21
hot-reload-test $ php artisan serve
Laravel development server started: 

npmでライブラリのインストール

JavaScriptライブラリのインストールを行います。


hot-reload-test $ npm install

インストール完了後、npm run hotを実行します。このコマンドを実行するとファイルの変更を検知して、webpackのビルドを自動で行うようになります。


hot-reload-test $ npm run hot

welcome.blade.phpの書き換え

インストール直後ではローカルサーバ(http://129.0.0.1:8080)にアクセスすると下記のページが表示されます。

Laravelインストール後の画面
Laravelインストール後の画面

ルーティングファイルweb.phpを確認すると上記に表示されている内容はresouces/views/welcome.blade.phpだということがわかります。


Route::get('/', function () {
    return view('welcome');
});

welcome.blade.phpのヘッダーの情報は残しつつ、デフォルトで作成済みのコンポーネントをexample-componet追加しています。vueのコンポーネント中で<div id=”app”></div>も追加してその中に入れる必要があります。

JavaScriptファイルとCSSのファイルの読み込みはhelper関数のmixを利用して設定を行っています。


<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Hot Module Replacemenet</title>
        <link rel="stylesheet" href="{{ mix('css/app.css') }}">
    </head>
    <body>

    <div id="app">
        <example-component></example-component>
    </div>
   
    <script src="{{ mix('js/app.js') }}"></script> 
    </body>
</html>

vueのコンポーネントの内容も表示されているので、Laravel上でvue.jsが動作していることがわかります。

welcome.blade.phpを書き換えたあとのページ
welcome.blade.phpを書き換えたあとのページ

上記では127.0.0.1:8000にアクセスしてますが、HMRの機能を使うためには、webpack-dev-serverが起動している127.0.0.1:8080にアクセスする必要があります。

127.0.0.1:8080にアクセスすることができますが、初期設定のままではCannot GET /が表示されてページの内容を確認することができません。

127.0.0.1:8080にアクセスした結果
127.0.0.1:8080にアクセスした結果

ページを表示させるためには、webpack.mix.jsに以下のコメントを追加する必要があります。


const mix = require('laravel-mix');

mix.webpackConfig({
    devServer: {
        proxy: {
            '*': 'http://localhost:8000'
        }
    }
});

変更後は設定を反映させるために一度npm run hotを停止して、再度npm run hotを実行してください。ブラウザをリロードすると下記の画面が表示されます。

npm run hotを再実行した結果
npm run hotを再実行した結果

本当にリアルタイムで変更が反映されるか確認するためにresources/js/componentsにあるExampleComponet.vueのVueファイルを更新してみましょう。


<div class="card-body">
    I'm an example component.
    I update this file. Check your Browser.
</div>

保存するとビルドが自動で行われ、更新された内容に画面が自動で変わります。

ExampleComponentsファイルの更新後の画面
ExampleComponentsファイルの更新後の画面

注意点

php artisan serveを実行する必要

php artisan serveを停止すると画面には下記が表示されます。

Error occured while trying to proxy to: 127.0.0.1:8080/

npm run hotを使用したい場合は、先にphp artisan serverを実行しておく必要があります。

bladeファイルの更新について

app.jsに関連するJavaScriptファイル、Vueファイル、CSSに関するapp.scssの更新をチェックしているので、welcome.blade.phpを変更した場合はページのリロードを手動で行う必要があります。