Vue 3 を Laravel 8で使う方法(npm)

こんにちは。フリーランス・コンサルタント&エンジニアの 九保すこひ です。

さてさて、Vue 3がリリースされてから少し経ちましたが、これまで、私の場合、npmを使ってLaravel 8.xと連携をしてきませんでした。

というのも、「いちいちビルドすると開発のテンポが悪くなり、保守もしたくなくなるから」というのが一番の理由なんですが、実際はそれ以外にも連携できない理由がありました。

それが・・・・・・

Laravel Mix が Vue 3 に完全対応してなかった

からです。

私はLaravelVueの大ファンなので、バージョン3が出てすぐにnpmで連携させようとしましたが、なんと「.vue」ファイルをうまくコンパイルすることができないことが分かりました。

いろいろ調べた結果、Laravel Mixの作者が「それは、次期バージョン6で対応するよ👍」と書いていたので、現在まで待ちに待っていました。

そして、数日前ついにLaravel Mixが新バージョン6になったので、この記事も再度加筆を加えて公開することにしました。

ぜひ皆さんのお役にたてると嬉しいです😊✨

「久しぶりに、ドキドキ待つ状態でした(笑)」

Vue 3 をインストールする

まずはVue 3本体をインストールします。
以下のコマンドを実行してください。

npm install vue@next --save-dev

インストールが完了するとpackage.jsonは以下のようになります。

ビルドする前に確認しておくべきこと

このままビルドできればいいのですが、実はLaravel 8.xがリリースされてすぐの頃は、ビルド・パッケージLaravel Mixのバージョンが5でした。

しかし、バージョン5のままではVue 3の「シングル・ファイル・コンポーネント」(いわゆる.vueファイル)をビルドすると以下のようなエラーが発生していました。

Vue packages version mismatch:

そのため、まずはpackage.jsonを開いて、laravel-mixの項目を探し、バージョンが6になっているかを確認してください。

"devDependencies": {
    "@tailwindcss/ui": "^0.5.0",
    "axios": "^0.19",
    "cross-env": "^7.0",
    "font-awesome": "^4.7.0",
    "laravel-mix": "^5.0.1", // 👈 ここのバージョンを確認してください
    "lodash": "^4.17.19",
    "postcss-font-awesome": "^0.4.0",
    "postcss-import": "^12.0.1",
    "resolve-url-loader": "^3.1.0",
    "sass": "^1.27.0",
    "sass-loader": "^8.0.2",
    "tailwindcss": "^1.3.0",
    "vue": "^3.0.4",
    "vue-template-compiler": "^2.6.12"
},

もし、5の場合だとLaravel Mixバージョン6にアップグレードする必要があります。手順は以下のとおりです。(もしバージョンが6の場合は問題ありませんので、次の項目へ移動してください)

Laravel Mix を 5 → 6へアップグレードする

【追記:2021.05.18】

パッケージを削除しないとバージョン6がインストールできなかったため、先に以下のコマンドを実行しておいてください。

npm uninstall laravel-mix

そして、以下のコマンドで新パッケージをインストールします。

npm install laravel-mix --save-dev

インストールが完了したら、以下のコマンドを実行してビルドができるかをチェックしてみてください。

npm run dev

※ もしこれでもエラーが出る場合は、Laravel Mixをアップグレードしたのにビルドできない場合にいくつかまとめていますので、そちらを確認してみてください。(⚠ おそらくこのままでは、エラーが出ると思います😅

Vue 3をビルドしてひとつのファイルにまとめる

npmでインストールしただけではVue 3Laravelで使えるようにはなっていません。

そのため、Laravel MixWebpack)でJavaScriptパッケージをビルドして、ひとつのファイルにまとめる作業をします。

では、「どのパッケージをひとまとめにするか?」が書かれているファイルにVueを登録してください。

resources/js/app.js

import { createApp } from 'vue/dist/vue.esm-bundler.js';
window.createApp = createApp;

では、設定が完了しましたので、実際にビルドしましょう!
以下のコマンドを実行してください。

npm run dev

なお、このコマンドはビルドスピードが早い、「開発向け」のコマンドです。
そのため、以下の警告がでると思います。

You are running the esm-bundler build of Vue. It is recommended to configure your bundler to explicitly replace feature flag globals with boolean literals to get proper tree-shaking in the final bundle. See http://link.vuejs.org/feature-flags for more details.

この場合は、本番環境向けのビルドにすれば警告は消えてくれます。

npm run prod

シングル・ファイル・コンポーネントをつくってみる

Vue 3のインストールが完了したので、以下を1つのファイルで作成することができる「シングル・ファイル・コンポーネント」を作ってみましょう。(いわゆる、拡張子が.vueのファイルです)

  • HTML
  • JavaScript
  • CSS

今回はテストとして、シンプルに「あいさつ」を表示するコンポーネント「Hello.vue」を作ってみましょう❗

.vueファイルをつくる

以下のファイルを作成してください。

resources/js/components/Hello.vue

<template>
    <div id="greeting_box">{{ greeting }}、みなさん!</div>
</template>

<script>

    module.exports = {
        data() {
            return {
                greeting: ''
            }
        },
        mounted() {

            const dt = new Date();
            const hours = dt.getHours();

            if(hours <= 4 || hours >= 18) {

                this.greeting = 'こんばんは';

            } else if(hours >= 12) {

                this.greeting = 'こんにちは';

            } else {

                this.greeting = 'おはようございます';

            }

        }
    }

</script>

<style scoped>

    #greeting_box {

        background-color: #ffeeee;

    }

</style>

※ なお、シングル・ファイル・コンポーネントの詳しい内容は、Laravel でシングルファイル・Vueコンポーネントをつくる方法をご覧ください。

.vueファイルのビルドを有効にする

続いて「Hello.vue」がビルドできるようにします。
以下のコードを記述してください。

resources/js/app.js

require('./bootstrap');

import { createApp } from 'vue/dist/vue.esm-bundler.js';
window.createApp = createApp;

window.HelloComponent = require('./components/Hello.vue').default; // 👈 ここを追加しました

コンポーネントをVueにセットする

この状態で「npm run dev」を実行するとビルドできますので、最後にVueにセットしてコンポーネントを使えるようにします。

<html>
<head>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
</head>
<body>
<div id="app">
    <!-- Hello コンポーネント -->
    <v-hello></v-hello>

</div>

<!-- 👇 この中にVue本体からコンポーネントまで全て入っています -->
<script src="{{ mix('js/app.js') }}"></script>

<script>

    createApp({
        // 省略
    })
    .component('v-hello', HelloComponent) // 👈 ここでセットしています
    .mount('#app');

</script>
</body>
</html>

うまくいくと以下のように表示されます。

Laravel Mixをアップグレードしたのにビルドできない場合

scripts の中身を変更する

まず以下のエラーが出る場合です。

[webpack-cli] Unknown argument: --hide-modules

これはLaravel Mixのバージョンが上がったことで発生しています。
そのため、package.json内にあるscripts項目を変更してください。

(変更前)

"scripts": {
    "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 --disable-host-check --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"
},

↓ ↓ ↓

(変更後)

"scripts": {
    "dev": "npm run development",
    "development": "mix",
    "watch": "mix watch",
    "watch-poll": "mix watch -- --watch-options-poll=1000",
    "hot": "mix watch --hot",
    "prod": "npm run production",
    "production": "mix --production"
}

※新バージョンでは、mixコマンドができたようですね👍

パッケージが揃っていない場合

もし以下のような表示が出たなら、それは「必要なパッケージが揃っていないからインストールしてます」という表示なので、そのコマンドが終わってから再度「npm run dev」を実行してください。

Additional dependencies must be installed. This will only take a moment.

...(省略)

Finished. Please run Mix again.

Tailwindが何か言ってくる

もし以下のような表示が出た場合は、「Tailwindをアップグレードしたほうがいいよ」と言っています。

risk - We highly recommend opting-in to these changes now to simplify upgrading Tailwind in the future.

これは、ビルドには関係ありません。
しかし、気になる場合は、以下のコマンドを実行してアップグレードできます。

npm install tailwindcss

半分だけ成功する

ビルドのコマンドを実行すると、

[webpack-cli] Compilation finished

と表示されるのに、ポップアップ通知には、

SyntaxError: Unexpected token ( 1:0 )

というエラーが表示されている場合は、webpack.mix.js.vue()を追加する必要があります。

mix.js('resources/js/app.js', 'public/js').vue() // 👈 ここです
    // 以降はお好みで変更してください
    .sass('resources/sass/app.scss', 'public/css')
    .options({
        postCss: [
            require('postcss-import')
        ]
    })
    .webpackConfig(require('./webpack.config'))
    .sourceMaps();

なお、バージョン2を使う場合はこうなります。

mix.js('resources/js/app.js', 'public/js').vue({ version: 2 });

おまけ: .mapに関する警告が出たら

ブラウザのコンソールに以下のような警告が表示された場合の対処法です。

DevTools failed to load SourceMap: Could not load content for http://******/js/index.js.map: HTTP error: status code 404, net::ERR_HTTP_RESPONSE_CODE_FAILURE

この場合は、以下のようにsourceMaps()を追加してビルドしなおしてください。

webpack.mix.js

mix.js('resources/js/app.js', 'public/js').postCss('resources/css/app.css', 'public/css', [
    require('postcss-import'),
    require('tailwindcss'),
]).sourceMaps(); // 👈 ここ
開発のご依頼お待ちしております
開発のご依頼はこちらから: お問い合わせ
どうぞよろしくお願いいたします! by 九保すこひ

おわりに

ということで、初めてこの記事を書き始めてから約3ヵ月を経て完成させることができました。

こんなブログなんて見てらっしゃらないでしょうが、Laravel Mix開発者のJeffrey Wayさん、どうもありがとうございます。m(_ _)m

ちなみに、ビルドが成功したときは以下のような表示になり、テンションが上がりました😊👍

ぜひ皆さんもやってみてくださいね。

ではでは〜❗

「年末に向けて食料を多めに買うと、
買った分だけ多めに食べて、
すぐまた買いにいくという・・・😭」

このエントリーをはてなブックマークに追加       follow us in feedly