カテゴリー
コンピューター

Laravel 6 で Vue.js 3 を使えるようにするまでの試行錯誤の記録

まとめ

  • Vue.js 3 を npm --save-dev vue@next でインストールした。
  • laravel-mix のバージョンを最新にする必要があり、それは npm audit fix --force で自然とそうなった。
  • vue-loader もバージョンを合わせる必要があり、そのバージョンは 16 で、インストール時の指定は、 npm install --save-dev npm-loader@next だった。
  • resources/js/app.js で Vue.js 3 の方法で初期化すれば良い。
  • Blade テンプレートファイルで Vue.js 3 を読み込むには、 <div id="app"></div><script src="js/app.js"></script> を書けば良い。

Vue.js 3 や依存パッケージのインストール

npm install し、 npm audit fix --force することで、 package.json の axios のバージョンが上がり、 laravel-mix のバージョンが 5 から 6 になりました。後から知りましたけれども、 laravel-mix 6 は Vue.js 3 を動かすために必須なようです。

$ npm run dev

> @ dev /var/www/html/laravel
> npm run development


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

        Additional dependencies must be installed. This will only take a moment.
 
        Running: npm install postcss@^8.1 --save-dev --legacy-peer-deps
 
        Finished. Please run Mix again.
 
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @ development: `cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --config=node_modules/laravel-mix/setup/webpack.config.js`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the @ development script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/app/.npm/_logs/2021-04-18T06_43_03_038Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @ dev: `npm run development`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the @ dev script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/app/.npm/_logs/2021-04-18T06_43_03_077Z-debug.log
$ 

エラーで終了しましたが、気にせずもう一度同じコマンドを実行したところ、正常に終了しました。

$ npm run dev

> @ dev /var/www/html/laravel
> npm run development


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


● Mix █████████████████████████ emitting (95%)  
 emit

● Mix █████████████████████████ done (99%) plugins 
 WebpackBar:done

✔ Mix
  Compiled successfully in 4.93s

                         
   Laravel Mix v6.0.16   
                         

✔ Compiled Successfully in 4853ms
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┬─────────┐
│                                                                                                                    File │ Size    │
├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┼─────────┤
│                                                                                                              /js/app.js │ 597 KiB │
│                                                                                                             css/app.css │ 1 bytes │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┴─────────┘
webpack compiled successfully
$ 

Vue.js 3 をインストールしました。

npm install vue@next --save-dev

package.json には次のように記されました。

$ git diff laravel/package.json
diff --git a/laravel/package.json b/laravel/package.json
index f506f34..7f8436f 100644
--- a/laravel/package.json
+++ b/laravel/package.json
@@ -17,6 +17,7 @@
         "postcss": "^8.2.10",
         "resolve-url-loader": "^3.1.0",
         "sass": "^1.15.2",
-        "sass-loader": "^8.0.0"
+        "sass-loader": "^8.0.0",
+        "vue": "^3.0.11"
     }
 }
$

この後、必要なファイルに手を加えて完成、、、となるのでしょうが、様々なウェブページを見たところ修正内容が結構あるようで、玄人じみたやり方は止めることにしました。参考ページの通り、の方法へ軌道修正します。

必要な依存パッケージを追加し、基盤となるファイルを生成しました。

composer require laravel/ui:^1.0 --dev
php artisan ui vue

どうやら laravel/ui はなくとも良いようですが、 package.json へ必要な依存パッケージを追加したり、便利なファイルの雛形を追加できたりと、初めてこの作業を行う際はメリットが大きそうです。極めたいときには、 laravel/ui なしでチャレンジする、というはありだと思います。

package.json の差分です。

$ git diff laravel/package.json
diff --git a/laravel/package.json b/laravel/package.json
index 7f8436f..17fb723 100644
--- a/laravel/package.json
+++ b/laravel/package.json
@@ -11,13 +11,17 @@
     },
     "devDependencies": {
         "axios": "^0.21.1",
+        "bootstrap": "^4.0.0",
         "cross-env": "^7.0",
+        "jquery": "^3.2",
         "laravel-mix": "^6.0.16",
         "lodash": "^4.17.19",
+        "popper.js": "^1.12",
         "postcss": "^8.2.10",
-        "resolve-url-loader": "^3.1.0",
-        "sass": "^1.15.2",
+        "resolve-url-loader": "^3.1.2",
+        "sass": "^1.20.1",
         "sass-loader": "^8.0.0",
-        "vue": "^3.0.11"
+        "vue": "^2.5.17",
+        "vue-template-compiler": "^2.6.10"
     }
 }
$

生成された、これは大事かな、と思えたファイルです。長いので、上書き元のファイルへのリンクです。

次回以降は、これらの変更を手動で施せば、 laravel/ui は不要なのではないかと思います。

コードを修正し、 エラーを解消する

npm run dev してみますと、エラーとなりました。

$ npm run dev

> @ dev /var/www/html/laravel
> npm run development


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


✖ Mix
  Compiled with some errors in 6.69s

ERROR in ./resources/js/components/ExampleComponent.vue 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> <template>
|     <div class="container">
|         <div class="row justify-content-center">

webpack compiled with 1 error
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @ development: `cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --config=node_modules/laravel-mix/setup/webpack.config.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @ development script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @ dev: `npm run development`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @ dev script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
$

次の部分が大事で、

ERROR in ./resources/js/components/ExampleComponent.vue 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> <template>
|     <div class="container">
|         <div class="row justify-content-center">

どうやら Vue.js を処理するものそのものが足りていないようです。おそらくこの アセットのコンパイル(Mix) 8.x Laravel が足りていないのでしょう。

次のように修正しました。

$ git diff laravel/webpack.mix.js
diff --git a/laravel/webpack.mix.js b/laravel/webpack.mix.js
index 19a48fa..879383f 100644
--- a/laravel/webpack.mix.js
+++ b/laravel/webpack.mix.js
@@ -12,4 +12,5 @@ const mix = require('laravel-mix');
  */

 mix.js('resources/js/app.js', 'public/js')
+   .vue()
    .sass('resources/sass/app.scss', 'public/css');

$

その後、 npm run dev を実行すると、追加で依存パッケージが自動的にインストールされ、結果的に失敗しました。

$ npm run dev

> @ dev /var/www/html/laravel
> npm run development


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

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

        Running: npm install vue-loader@^15.9.5 --save-dev --legacy-peer-deps

        Finished. Please run Mix again.

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @ development: `cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --config=node_modules/laravel-mix/setup/webpack.config.js`
npm ERR! Exit status 1
... 以下略 ...
$

ですが、もう一度 npm run dev を実行すると、今度は成功しました。以上でエラー解消に関しては、完了です♪

もう一度 Vue.js 3 をインストールする

laravel/ui のインストールにより、 Vue.js 2 となってしまいましたので、 Vue.js 3 へと戻します。 npm install vue@next --save-dev を実行しました。

その後、 npm run dev を行い、@vue/compiler-sfc が自動的にインストールされ、ビルドに失敗しました。そして、もう一度 npm run dev を行い、ビルド成功、、、しませんでした。

$ npm run dev

> @ dev /var/www/html/laravel
> npm run development


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


✖ Mix
  Compiled with some errors in 7.44s

ERROR in ./resources/js/components/ExampleComponent.vue
Module Error (from ./node_modules/vue-loader/lib/index.js):


Vue packages version mismatch:

- vue@3.0.11 (/var/www/html/laravel/node_modules/vue/index.js)
- vue-template-compiler@2.6.12 (/var/www/html/laravel/node_modules/vue-template-compiler/package.json)

This may cause things to work incorrectly. Make sure to use the same version for both.
If you are using vue-loader@>=10.0, simply update vue-template-compiler.
If you are using vue-loader@<10.0 or vueify, re-installing vue-loader/vueify should bump vue-template-compiler to the latest.

... 以下略 ...

npm update すれば治るかもとやってみましたが、解決しませんでした。 vue-template-compiler を再インストールしてみたり、バージョンが最新であること確認してみたりしましたけれども、やっぱりダメでした。

うまくいっている状態を参考にしたいと思い、 Laravel8でVue 3を使う | アールエフェクト の "コンパイルが正常に完了した時のpackage.jsonファイルの中身は下記の通りです。" 部分の package.json を比較したところ、 vue-loader のメジャーバージョンが参考ページの方が高い、これだ、と思い試したところ、ビンゴでした!ただ単にアップデート、 npm update vue-loader しただけではダメで、次のようにバージョン指定でインストールする必要がありました。

npm install --save-dev vue-loader@next

コードを修正し、 Vue.js 3 を動かす

まず resources/js/app.js を修正して Vue.js 3 を初期化するような処理をします。ファイルを次の内容となるように書き換えました。

require('./bootstrap');

import { createApp } from 'vue'
import ExampleComponent from './components/ExampleComponent.vue'

 createApp({
    components:{
        ExampleComponent
    }
}).mount('#app')

元々のファイルからの違いとしては次のようになりました。

$ git diff laravel/resources/js/app.js
diff --git a/laravel/resources/js/app.js b/laravel/resources/js/app.js
index aa19e31..ba7c6d2 100644
--- a/laravel/resources/js/app.js
+++ b/laravel/resources/js/app.js
@@ -6,7 +6,7 @@

 require('./bootstrap');

-window.Vue = require('vue');
+import { createApp } from 'vue'

 /**
  * The following block of code may be used to automatically register your
@@ -19,7 +19,7 @@ window.Vue = require('vue');
 // const files = require.context('./', true, /\.vue$/i)
 // files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default))

-Vue.component('example-component', require('./components/ExampleComponent.vue').default);
+import ExampleComponent from './components/ExampleComponent.vue'

 /**
  * Next, we will create a fresh Vue application instance and attach it to
@@ -27,6 +27,8 @@ Vue.component('example-component', require('./components/ExampleComponent.vue').
  * or customize the JavaScript scaffolding to fit your unique needs.
  */

-const app = new Vue({
-    el: '#app',
-});
+ createApp({
+    components:{
+        ExampleComponent
+    }
+}).mount('#app')
$

この JavaScript を HTML 側のファイルの laravel/resources/views/welcome.blade.php で読み込みました。 Vue.js 3 が機能している事を確かめるのが目的なので、適当な場所に <div id="app"></div><script src="js/app.js"></script> を書きました。このとき、シングルファイルコンポーネントjにて Vue.js 3 を確認したかったですので、 <example-component></example-component> も書くようにしました。

$ git diff laravel/resources/views/welcome.blade.php
diff --git a/laravel/resources/views/welcome.blade.php b/laravel/resources/views/welcome.blade.php
index 7bc3372..919a93c 100644
--- a/laravel/resources/views/welcome.blade.php
+++ b/laravel/resources/views/welcome.blade.php
@@ -64,6 +64,10 @@
         </style>
     </head>
     <body>
+        <div id="app">
+            <example-component></example-component>
+        </div>
+        <script src="js/app.js"></script>
         <div class="flex-center position-ref full-height">
             @if (Route::has('login'))
                 <div class="top-right links">
$

最後に、 laravel/resources/js/components/ExampleComponent.vue も修正して、 Vue.js 3 の機能が使えるかどうか確認できるコードを追加しました。

$ git diff laravel/resources/js/components/ExampleComponent.vue
diff --git a/laravel/resources/js/components/ExampleComponent.vue b/laravel/resources/js/components/ExampleComponent.vue
index 3fb9f9a..7713967 100644
--- a/laravel/resources/js/components/ExampleComponent.vue
+++ b/laravel/resources/js/components/ExampleComponent.vue
@@ -2,6 +2,7 @@
     <div class="container">
         <div class="row justify-content-center">
             <div class="col-md-8">
+                <div>{{ message }}</div>
                 <div class="card">
                     <div class="card-header">Example Component</div>

@@ -15,7 +16,15 @@
 </template>

 <script>
+    import { ref } from "vue";
     export default {
+        setup() {
+            const message = ref("Hello Laravel Vue 3");
+
+            return {
+              message
+            };
+        },
         mounted() {
             console.log('Component mounted.')
         }

$

以上で Vue.js 3 が Laravel 6 で動くかどうかを確認するためのコード追加は完了です。

http://localhost/ にアクセスしてみますと、 Example Component の狙った部分が表示されており、成功です!

おわりに

今回やりたかった、 Laravel 6 で Vue.js 3 を使う、が無事できました♪ただし、特に package.json 周りに無駄が多いように思います。

最低限の追加で今回と同じことが実現できるようにしてみたいものです。

最後に、参考ページを改めて記載します。大変助かりました。ありがとうございました!

以上です。

コメントを残す