へっぽこ社会人4年生がプログラミングを頑張る

へっぽこ社会人4年目がプログラミング系統を中心に書きたいことをつらつらと書きます

LaravelにVuetifyをインストールする方法

Laravelでは、デフォルトでVue.jsをサポートしており、バンドルツールのWebpackも簡単に使えます。ただ、流石にいい感じのUIコンポーネントを自前で1から作るのは大変なので、Vue.jsのフレームワークとして有名な Vuetify を採用してみることにしました。

Vuetifyのドキュメントを参考にしながらインストールや設定を行ったのですが、結構苦労したので、備忘録として残しておくことにします。Laravel, Vue.js, Laravel-Mix, Vuetify のバージョンはそれぞれ以下の通りです。

  • Laravel: 5.8.31
  • Vue.js: 2.6.10
  • Laravel-Mix: 4.1.2
    • Webpack: 4.39.1
  • Vuetify: 2.0.5

Vuetifyのインストールの流れ

Laravelには、デフォルトではVuetifyは入っていないので、パッケージのインストールと設定が必要です。また、今回はLaravel-Mixでコンパイルもしてもらいたいので、Vuetify-LoaderをインストールとWebpackの設定も必要です。

手順の概要は以下の通りです。

  1. VuetifyとVuetify-Loaderをインストール
  2. webpack.mix.js にVuetify-Loaderをプラグインとして設定
  3. Vuetifyの設定ファイルを作成して app.js のVueインスタンスに追加

VuetifyとVuetify-Loaderのインストール

Laravelのプロジェクトディレクトリ配下で npmyarn を使ってインストールします。今回はLaravel-MixでVuetifyのコンポーネントコンパイルしたいので、CDNは用いないことを想定しています。

npm install vuetify -S
npm install vuetify-loader -D

Vuetify はアイコンにアイコンフォントを利用するので、インストールします。

npm install @mdi/font -D

Webpackの設定

VuetifyとVuetify-Loaderをインストールしたら、Webpackの設定をします。Laravel-MixでのWebpackの設定は、 webpack.mix.js に記述します。Webpackの設定は、Laravel-Mixの webpackConfig メソッドを用います。 webpackConfig メソッドの引数には、Webpackの設定で module.export するオブジェクトと同様のものを指定するようです。

Vuetify-Loaderを読みこませるために、 'vuetify-loader/lib/plugin を読み込み、Vuetify-Loaderのインスタンスplugins プロパティに設定します。 webpack.mix.js の中身は以下の通りです。

const mix = require('laravel-mix');
const VuetifyLoaderPlugin = require('vuetify-loader/lib/plugin');

mix.webpackConfig({
  plugins: [
    new VuetifyLoaderPlugin(),
  ],
});

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

Vuetifyの設定

公式ドキュメントでは、 src/plugins/vuetify.js に、VuetifyをVue.jsのプラグインとして読み込ませる方法が書いてありますが、Laravelのディレクトリ構造と異なるので、 resources/js/plugins/vuetify.js に記述することとします。設定ファイルの場所が違うこと以外は、基本的には公式ドキュメントと同様に設定します。

まず、設定ファイルを、公式ドキュメントと同様に resources/js/plugins/vuetify.js に記述します。アイコンフォントの設定もここで行います。アイコンフォントのモジュールを読み込み、Vuetifyインスタンスの引数のオブジェクト内に記述します。

import '@mdi/font/css/materialdesignicons.css';
import Vue from 'vue';
import Vuetify from 'vuetify/lib';

Vue.use(Vuetify);

export default new Vuetify({
  icons: {
    iconfont: 'mdi',
  },
});

Vuetifyをプラグインとして読み込ませるために、 resources/js/app.js を以下のように編集します。

require('./bootstrap');

window.Vue = require('vue');
import vuetify from './plugins/vuetify';

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

これで、Laravel-MixでもVuetifyのコンポーネントが使えるようになります。全てのコンポーネントについて検証したわけではありませんが、明示的にVuetifyのコンポーネントimport していなくても、問題なく利用できるようになっているはずです。

ハマった点

自分で設定をしている際に、以下の2つの点でハマりました。

  1. Vuetifyのコンポーネントが読み込まれないものがある
  2. VuetifyのデフォルトのCSSが効いてない

Vuetifyのコンポーネントが読み込まれないものがある

最初、Webpackの設定しか書いていませんでした。Webpackの設定自体は通り、試しに v-btn コンポーネントを利用した際には、問題なく表示されました。 v-card も同様に使えました。

これで使えるようになったと糠喜びをしていたのも束の間、 v-pagination を試したら画面上に表示されず、コンソールにエラーが出力されていました。

[Vue warn]: Error in render: TypeError: this.$vuetify is undefined v-pagination

どうやら、Vuetify-Loaderの制約で、 Dynamic ComponentFunctional Component は手動で読み込まないと使えないようです。 ドキュメントを読んだのですが、どうしても Functional Component がどのようなものかイマイチはっきり分からず、どのコンポーネントFunctional Component に当たるか区別がつかないので、別の手段を模索しました。

Vuetify-Loader で全部読み込みきれなかったようだったので、次は Vuetify の設定ファイルのみ作って、コンパイルしなおしましたが、今度はVuetifyがうまく動かなくなったようでした。結局、Vuetify-LoaderとVuetifyの設定の両方を書いたら、問題なく動くようになりました。

この辺りについて、自分自身で完全に理解しきれていないので、どなたか助言をいただけると、個人的に大変助かります。

VuetifyのデフォルトのCSSが効いていない

結論から書くと、 v-app の中にVuetifyのコンポーネントを入れ忘れていただけでした。公式ドキュメントにも、Vuetifyのコンポーネントは、 v-app の中に入れろと書いていましたが、とりあえずVuetifyのコンポーネントが動くか試したかったので、そのことをすっかり忘れていました。とても初歩的なミスでした。

v-app を書き忘れていることに気づくまで、Vuetifyの設定を色々いじっていました。 v-btn のデフォルトの背景色はCSS効いてるっぽいけど、フォントが違ったり、 class="primary" を指定しても背景色が変わらなかったりで、コンポーネントCSSを明示的に読み込まなければいけないのかと勘違いしていました。

まとめ

LaravelにVuetifyをインストールする場合、Vue CLI 3を利用するのとは少し勝手が違うので、設定に苦戦しました。とりあえず、 Vuetify-LoaderをLaravel-MixのWebpackにプラグインとして読み込ませ、VueインスタンスにVuetifyをプラグインとして読み込ませれば、各SFCでVuetifyのコンポーネントimport を書かなくても、自動で読み込まれるようになりました。

自分自身、挙動を完璧に理解しきれていないので、もし詳しい方がいらっしゃれば、ご教授願えればと思います。

参考文献