⛩️

Laravel9+Vuetify3で自動インポート(旧vuetify-loader)を導入する

2022/06/11に公開

Vuetify3でTreeshaking(自動インポート・容量削減)をしようとしたら、どうやらvuetify-loaderじゃなくなったらしいのでVuetify3の導入方法と共にメモで残します。
ググっても見つからなかったので。

https://next.vuetifyjs.com

Environment

PHP     ->   v8.0.14
Laravel ->   v9.2
node    ->   v16.13.2
vue     ->   3.2.36
vuetify ->   3.0.0-beta.3 (@next)

Laravel9+Vue3導入

私が書いた以下の記事を見てみて下さい。割愛します。

https://0115765.com/archives/7336

Vuetify3インストール

Vue3に対応したVuetify3をインストール

npm i vuetify@next
// vuetify: ^3.0.0-beta.3

resource/js配下のapp.ts(Typesciptを使ってないなら.js)を以下に変更。

/resources/js/app.ts
import "vuetify/styles";
import {createVuetify} from 'vuetify';

import router from "./route";
import {createApp} from 'vue';
import App from './App.vue';

const vuetify = createVuetify();

const app = createApp({
    components: {
        App,
    }
});
app.use(router);
app.use(vuetify);
app.mount('#app');

ここで注意なのが、Vue内で<v-xxxx>のようVuetifyコンポーネントを呼び出す処理は後のTreeshakingで自動インポートするので態々個別にインポートする必要はありません。

Vuetify3で自動インポートするには

本題。Vuetifyはかなり幅広い部分までカバーしてくれている分、使わないコンポーネントまで読み込んでビルドサイズが肥大になりがちです。対策として各単一ファイルコンポーネント内でimport ~~で読んでいいですが、面倒。
そんなとき、Vuetify2ではvuetify-loaderでTreeshakingを行うのが最も便利とされていました。

https://github.com/vuetifyjs/vuetify-loader/tree/next

vuetify-loaderをVuetify3で使うにはnpm i vuetify-loader@nextで出来るよ~とググったら出てきたのですが、どうやら作者によるとWebpackを使う場合はwebpack-plugin-vuetify を使えと言われてた。

https://github.com/vuetifyjs/vuetify-loader/blob/next/README.md

なので、公式に則って導入します。Treeshakingの仕組みは以下に詳しく書いてあります。
https://github.com/vuetifyjs/vuetify-loader/tree/next/packages/webpack-plugin

webpack-plugin-vuetifyインストール

NPMでインストール。

npm i webpack-plugin-vuetify

あとは、Laravel MixのWebpack設定に以下を追記するだけ。

webpack.mix.js
+ const {VuetifyPlugin} = require('webpack-plugin-vuetify');

+ mix.webpackConfig({
+     plugins: [
+         new VuetifyPlugin({autoImport: true}), // Enabled by default
+     ],
+ });

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

ドキュメントによればautoImport: trueで自動インポートしてくれるそうです。
最後にちゃんとVuetify3+Treeshakingが動作するか確認。

ExampleComponent.vue
<template>
    <v-app>
    <v-app-bar>
        <v-app-bar-title>
            <span>Demo</span>
        </v-app-bar-title>
    </v-app-bar>
    </v-app>
</template>

npm run prod

全部Vuetifyのコンポーネントを読み込むとMinifyしても1MB程度ですが、数百キロバイトになります。VuetifyのCSSをpurgeCSSを通すと更に容量削減できますー

更に容量削減する

通常、Laravel MixプロジェクトのCSSのアセットサイズを削減するにはPurgeCSSを使いますが、どうやら自分の環境ではエラーが発生します。
ですが、以下のようにCSSを読み込む場所をTSファイル内からScssファイルに切り替えると、何故か790KB→400KB程度まで削減されます。

resources/app.ts
- import {createVuetify} from 'vuetify';
resources/sass/app.scss
+ @import "vuetify/lib/styles/main";

備考:自動インポートしない方法

テスト用で別にTreeshakingはいらないなら以下ですぐ終わり。
ただ、プロダクションビルドした際にファイルサイズがかなり大きくなるので注意です。

app.ts
import * as components from 'vuetify/components';
import * as directives from 'vuetify/directives';
const vuetify = createVuetify({
    components,
    directives,
});

Discussion