Laravel sail でVuetify3 を動かしている記事は探せば沢山見つかるのですが、
実際に使ってみるとVuetify3 だと上手く動かない事例があった際に、対応への参考になる記事や書き込みが少なくて挫折しました。
では、記事やチュートリアルが多いVuetify2 で環境構築やってみようという事で導入の記録を残してみます。
環境
Windows 10
Vscode(Remote Development)
WSL:Ubuntu on Windows
Docker Desktop 4.15.0
初期設定
まずはsailのインストール
初期設定で参考にしたのは
こちら(https://kataen.com/docker-laravel-sail-vue-windows)
cd ~ でホームディレクトリに移動してからコマンドを入力しないと後で困ります。
cd ~
curl -s https://laravel.build/<アプリ名> | bash
docker-compose.ymlの修正
サービスの所をアプリ名にしておくと良いようです。
コマンドでsqlやらのサービスを指定する方法もあるんですが、サービス名を手動で変えるからymlを編集するんですかね。
# For more information: https://laravel.com/docs/sail
version: '3'
services:
<アプリ名>:
build:
context: ./vendor/laravel/sail/runtimes/8.1
dockerfile: Dockerfile
args:
WWWGROUP: '${WWWGROUP}'
image: sail-8.1/app
extra_hosts:
- 'host.docker.internal:host-gateway'
ports:
- '${APP_PORT:-80}:80'
- '${VITE_PORT:-5173}:${VITE_PORT:-5173}'
environment:
WWWUSER: '${WWWUSER}'
LARAVEL_SAIL: 1
XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}'
XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}'
volumes:
- '.:/var/www/html'
networks:
- sail
depends_on:
- pgsql
- mailhog
pgsql:
image: 'postgres:14'
ports:
- '${FORWARD_DB_PORT:-5432}:5432'
environment:
PGPASSWORD: '${DB_PASSWORD:-secret}'
POSTGRES_DB: '${DB_DATABASE}'
POSTGRES_USER: '${DB_USERNAME}'
POSTGRES_PASSWORD: '${DB_PASSWORD:-secret}'
volumes:
- 'sail-pgsql:/var/lib/postgresql/data'
- './vendor/laravel/sail/database/pgsql/create-testing-database.sql:/docker-entrypoint-initdb.d/10-create-testing-database.sql'
networks:
- sail
healthcheck:
test: ["CMD", "pg_isready", "-q", "-d", "${DB_DATABASE}", "-U", "${DB_USERNAME}"]
retries: 3
timeout: 5s
mailhog:
image: 'mailhog/mailhog:latest'
ports:
- '${FORWARD_MAILHOG_PORT:-1025}:1025'
- '${FORWARD_MAILHOG_DASHBOARD_PORT:-8025}:8025'
networks:
- sail
networks:
sail:
driver: bridge
volumes:
sail-pgsql:
driver: local
envの修正
APP_SERVICE とWWWUSER、WWWGROUP、DB_DATABASE を追記
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:XXXXXXXXXXXXXXXXXXXXXXXXXXX
APP_DEBUG=true
APP_URL=http://localhost
APP_SERVICE=<サービス名>
WWWUSER=1000
WWWGROUP=1000
LOG_CHANNEL=stack
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
DB_CONNECTION=pgsql
DB_HOST=pgsql
DB_PORT=5432
DB_DATABASE=<サービス名>
DB_USERNAME=sail
DB_PASSWORD=password
BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DISK=local
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
MEMCACHED_HOST=memcached
REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_HOST=
PUSHER_PORT=443
PUSHER_SCHEME=https
PUSHER_APP_CLUSTER=mt1
VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
VITE_PUSHER_HOST="${PUSHER_HOST}"
VITE_PUSHER_PORT="${PUSHER_PORT}"
VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
.bashrcの追記
Remote – WSL だと.bashrc 等をVScodeで編集できるので楽ですよね。
alias sail='[ -f sail ] && bash sail || bash vendor/bin/sail'
sail初回起動
cd <サービス名>
sail up -d
環境構築 Vue編
参考にしたのは
こちら(https://zenn.dev/dozo/articles/0263465546592c)
sail なのでvite はもとよりはいってます。
sail npm i vue@2.6.14
sail npm i -D vite-plugin-vue2 vue-template-compiler@2.6.14
古いので警告が出る
npm WARN deprecated sourcemap-codec@1.4.8: Please use @jridgewell/sourcemap-codec instead
npm WARN deprecated querystring@0.2.1: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
初回は2度ビルドする必要があるようです。
一度ビルドしたらCtrl+Cしてもう一度ビルド
sail npm run dev
VITE v4.0.4 ready in 459 ms
➜ Local: http://localhost:5173/
➜ Network: http://172.21.0.4:5173/
➜ press h to show help
LARAVEL v9.45.1 plugin v0.7.3
➜ APP_URL: http://localhost
成功画面の Local のアドレスをCtrl+クリックで
LaravelViteのフロントページが
APP_URL のアドレスをCtrl+クリックで
Laravelのフロントページが
それぞれ開くので表示されることを確認しておく。
環境構築Vue2編
必要なものをインストール
参考にしたのは
こちら(https://zenn.dev/404_notfound/articles/d4eea560196dba)
こちらも(https://github.com/logue/vite-vue2-vuetify-ts-starter)
数が多いときは1つ1つインストールしていかないと、どこでエラー出たのかわからなくなる。
sail npm i -D vue-router@3.6.5
sail npm i -D @vitejs/plugin-vue2
sail npm i -D vuetify@2.6.13
sail npm i -D unplugin-vue-components@0.22.12
sail npm i -D bootstrap-vue@2.23.1
sail npm i -D bootstrap@4.6.2
sail npm i -D vite-plugin-compression
sail npm i -D rollup-plugin-visualizer
sail npm i -D @mdi/font
sail npm i -D sass@1.32.13
sail npm i -D sass-loader@10.1.1
古いものが混じっていますので、すでにある環境に追加するときはご注意ください。
5 high severity vulnerabilities
上記のような警告が出ている場合は
以下のコマンドで出なくなります。
sail npm audit fix
app.jsを設定
resource/jp/app.js を開きます。
import "./bootstrap"; のみ書かれていると思いますのでそこに追記。
./components/App.vue は後から作ります。
import "./bootstrap";
import Vue from "vue";
import App from "./components/App.vue";
import Vuetify from "vuetify";
import axios from "axios";
import "@mdi/font/css/materialdesignicons.css";
import router from "./router";
import { BootstrapVue, IconsPlugin } from "bootstrap-vue";
import "bootstrap/dist/css/bootstrap.css";
import "bootstrap-vue/dist/bootstrap-vue.css";
Vue.use(BootstrapVue);
Vue.use(IconsPlugin);
Vue.http = Vue.prototype.$http = axios;
Vue.config.productionTip = false;
Vue.use(Vuetify);
const app = new Vue({
el: "#app",
router,
components: { App },
vuetify: new Vuetify(),
render: h => h('router-view'),
render: h => h(App),
});
console.log(app)
vite.config.js
./vite.config.js を開きます。
下記の様なファイルです。
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
input: ['resources/css/app.css', 'resources/js/app.js'],
refresh: true,
}),
],
});
下記のように記述します。
書き換えがめんどくさかったらコピペしてください。
import { defineConfig } from 'vite';
import viteCompression from 'vite-plugin-compression';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue2'
import { visualizer } from 'rollup-plugin-visualizer';
import Components from "unplugin-vue-components/vite";
import { VuetifyResolver } from "unplugin-vue-components/resolvers";
import path from "path";
export default defineConfig({
define: { 'process.env': {} },
resolve: {
alias: {
'@': path.join(__dirname, './resources/src'),
'~': path.join(__dirname, './node_modules'),
'vue$': 'vue/dist/vue.esm.js'
},
extensions: ['.js', '.vue', '.json', '.css', '.node']
},
css: {
postcss: {
plugins: [
// Fix vite build includes @charset problem postcss@8.4.20
{
postcssPlugin: 'internal:charset-removal',
AtRule: {
charset: atRule => {
if (atRule.name === 'charset') {
atRule.remove();
}
},
},
},
],
},
},
// Build Options
build: {
// Build Target
target: 'esnext',
// Rollup Options
rollupOptions: {
// @ts-ignore
output: {
manualChunks: {
// Split external library from transpiled code.
vue: [
'vue',
'vue-router',
'vue-router/composables',
],
vuetify: [
'vuetify/lib',
],
materialdesignicons: ['@mdi/font/css/materialdesignicons.css'],
},
plugins: [
visualizer({
open: true,
filename: 'dist/stats.html',
})
],
},
},
// Minify option
minify: 'esbuild',
},
plugins: [
laravel({
input: ['resources/css/app.css', 'resources/js/app.js'],
refresh: true,
}),
vue(),
viteCompression(),
Components({
resolvers: [VuetifyResolver()],
}),
],
server: {
hmr: {
host: 'localhost',
},
},
base: "./"
});
vue.config.js
vite.config.js と同じ階層に
vue.config.js を新たに作成してください。
下記のように記述します。
module.exports = {
publicPath: './',
css: {
loaderOptions: {
sass: {
prependData: `@import "@/sass/app.sass"`
additionalData: `@import "@/sass/common.sass";`
},
scss: {
prependData: `@import "@/sass/app.scss";`
additionalData: `@import "@/sass/common.scss";`
}
}
},
transpileDependencies: ['vuetify']
}
今回指定した
/resources/css/app.css
/resources/src/sass/common.sass
/resources/src/sass/common.scss
/resources/src/sass/app.sass
/resources/src/sass/app.scss
を空ファイルで良いので作成しておきます。
Vuetifyが作ってくれるスタイルで、気に入らないところを変えるのに使います。
フォーカスが当たったらテキストチェンジするとかの機能をCSSで作る時などでしょうか。
ルーティング
設定が多いですが、もう少しお付き合い願います。
/routes/web.php を編集します。
以下の様なファイルになっていると思います。
<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
このファイルの最下部に下記のように設定を追加。
Route::get('/app/{any?}', function () {
return view('app');
})->where('any', '.*');
Vue-Router の設定
先ほど編集したapp.js と同じ階層に
router.js ファイルを作成します。
記述は以下になります。
import Vue from "vue";
import VueRouter from "vue-router";
import Home from "./components/Home.vue";
import NotFound from "./components/404.vue";
Vue.use(VueRouter);
const routes = [
{
path: "/",
name: "Home",
component: Home,
},
{
path: "/404",
name: "404-NotFound",
component: NotFound,
},
{
path: "/:pathMatch(.*)",
redirect: "/404",
},
];
const router = new VueRouter({
mode: "history",
base: "/app",
routes,
});
export default router;
これでVueファイルを表示するための設定が完了しました。
ページ作成
表示に使うapp.blade.php の作成。
表示のひな型となるファイルを作成します。
resource/viewsにあるwelcome.blade.php と同じ位置に
新たにapp.blade.php を作成します。
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Fonts -->
<link rel="dns-prefetch" href="//fonts.gstatic.com">
<link href="https://fonts.bunny.net/css?family=Nunito" rel="stylesheet">
<!-- CSS&Scripts -->
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
<div id="app"></div>
</body>
</html>
Vueファイルの作成
やっとVuetify に入ります。
resourceフォルダのjsフォルダにcomponentsフォルダを作成します。
こちらにApp.vue Home.vue 404.vue と新たに3つファイルを作成します。
<template>
<v-app id="app">
<v-app-bar dense max-height="48px" color="orange accent-1">
<v-app-bar-nav-icon variant="text" @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
<v-toolbar-title>Vuetify</v-toolbar-title>
<v-spacer></v-spacer>
<v-menu offset-y>
<template v-slot:activator=" { on } ">
<v-btn
color="primary"
dark
v-on="on"
>
Dropdown
</v-btn>
</template>
<v-list>
<v-list-item
v-for="(item, index) in items"
:key="index"
>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-app-bar>
<v-navigation-drawer
v-model="drawer"
clipped
absolute
color="deep-orange darken-4"
>
<v-list
>
<v-list-item
exact
v-for="(item, i) in items"
:key=i
:to=item.to
>
<v-list-item-title v-text="item.title"></v-list-item-title>
</v-list-item>
</v-list>
</v-navigation-drawer>
<v-main>
<div class="pa-3">
<router-view></router-view>
</div>
</v-main>
</v-app>
</template>
<script>
export default {
name: 'app',
data: () => ({
drawer: null,
items : [
{
title: 'Home',
to: '/',
},
{
title: '404',
to: '/404',
},
],
}),
}
</script>
<style scoped>
html {
overflow: auto !important;
}
</style>
<template>
<div>
<div>
<h2>Vuetifyの表示テスト</h2>
<v-btn color="primary" class="mr-2 mb-2">
Normal
</v-btn>
<v-btn color="secondary" class="mr-2 mb-2">
Secondary
</v-btn>
<v-btn variant="outlined" color="error" class="mr-2 mb-2">
Error
</v-btn>
<v-btn disabled class="mr-2 mb-2">
Disabled
</v-btn>
<v-btn color="success" class="mr-2 mb-2">
Success
<v-icon
dark
right
>
mdi-checkbox-marked-circle
</v-icon>
</v-btn>
</div>
<div class="mt-3">
<h2 class="mt-3">mdi-Iconの表示テスト</h2>
<v-icon icon="mdi-home" class="mr-2">mdi-home</v-icon>
<v-icon icon="mdi-login" color="error" class="mr-2" >mdi-login</v-icon>
<v-icon icon="mdi-account" color="success" class="mr-2">mdi-account</v-icon>
<v-icon icon="mdi-account" class="mr-2" size="x-large">mdi-account</v-icon>
</div>
</div>
</template>
<template>
<div>
<H1>404</H1>
<p>ページが見つかりません</p>
</div>
</template>
<script></script>
<style scoped>
@media (max-width: 1000px){
div{
background: LightCyan;
width: 100vw;
height: 80vh;
}
}
</style>
作成が終わったら、いよいよ表示テストです。
表示テスト
コマンドを打ってビルドしたら表示を確認してください。
アドレスはこちら(http://localhost/app)
sail npm run dev
ビルドに問題がなければ下記ページが表示されます。
> dev
> vite
VITE v4.0.4 ready in 562 ms
➜ Local: http://localhost:5173/
➜ Network: http://172.22.0.4:5173/
➜ press h to show help
LARAVEL v9.45.1 plugin v0.7.3
➜ APP_URL: http://localhost
お疲れ様
とりあえずはVuetify で表示するまではできました。
sail+vite 以外なら楽に構築できるのですが、sailだと便利な開発環境にするには時間がかかります。
構築していて古い情報と新しい情報がミスマッチしており、これの確認が大変でした。
ひとまずは同じ環境を再現してもらえる記事になったのではないでしょうか。