DEV Community

Ichi
Ichi

Posted on

Starter Template of Laravel+Vite+Vuetify3+TypeScript+Router+Sass

Memorandum on building a Laravel + Vuetify3 environment. (I'm all about React)

I've also published the environment template I created on Github. please check below repository and use as template.


Image description

Laravel is changing rapidly, and Vuetify v3 is still in beta, so please issue or comment if you have any fixes.

Image description

Manually Setup

Laravel+Vite

composer create-project --prefer-dist laravel/laravel:^9.x *********
Enter fullscreen mode Exit fullscreen mode

When the Laravel project setup is complete, you may have found Laravel Mix-related packages in package.json, but now they have been replaced with Vite packages, so install them.

npm i
Enter fullscreen mode Exit fullscreen mode

Vue3+Vuetify3+Vue Router

The next step is to install Vue-related items.
For Vue3, just install the Vite plugin package called @vitejs/plugin-vue

npm i @vitejs/plugin-vue vue
Enter fullscreen mode Exit fullscreen mode
npm i vuetify@next vue-router
Enter fullscreen mode Exit fullscreen mode

(caution)about TypeScript

In the case of Laravel Mix, it is originally necessary to install various transpilers here, but in Vite's environment, TypeScrip is not required. Continue on to the next step.
But be careful that Vite with Laravel does not perform TypeScript type checking. The point seems to be to just transpile and use Volar or something.

Vite only performs transpilation on .ts files and does NOT perform type checking. It assumes type checking is taken care of by your IDE and build process. SOurce: Vite with Laravel Using TypeScript

Also, for Sass, install a transpiler.

npm i sass -D
Enter fullscreen mode Exit fullscreen mode

create app.ts

Create app.ts, the main JavaScript source, and load Vuetify, Router, etc.

import './bootstrap'
import 'vuetify/styles' // Global CSS has to be imported
import { createApp } from 'vue'
import { createVuetify } from 'vuetify'
import App from './App.vue'
// Route(next section)
import router from "./route"

const app = createApp(App)
const vuetify = createVuetify()

app.use(router)
app.use(vuetify)
app.mount('#app')

Enter fullscreen mode Exit fullscreen mode

create Vue SFC

As with Laravel Mix, we will develop the front-end in the /resources directory, including Router configuration files, components for each page, and so on.
Note: If you omit the extension when importing Vue components, an error will occur.

<template>
  <v-container class="counter">
  <!-- class="container" is added to check Sass behavior. -->
    <router-view></router-view>
  </v-container>
</template>
Enter fullscreen mode Exit fullscreen mode
import TopPage from './pages/TopPage.vue';
import NextPage from './pages/NextPage.vue';
import { createRouter, createWebHistory } from 'vue-router';

const routes = [
    {
        path: '/',
        name: 'TopPage',
        component: TopPage,
    },
    {
        path: "/next",
        name: 'NextPage',
        component: NextPage,
    },
];
const router = createRouter({
    routes,
    history: createWebHistory(),
})
export default router;
Enter fullscreen mode Exit fullscreen mode

Make components for each page as well. (Omit all but the top page.)

<template>
  <p>Top Page</p>
  <h1>{{ count }}</h1>
  <v-btn color="blue" @click="count++">Increment</v-btn>

  <router-link to="/next">To Next Page →</router-link>
</template>

<script setup lang="ts">
import { ref } from "vue";
const count = ref<number>(0);
</script>
Enter fullscreen mode Exit fullscreen mode

create Sass file

#app {
    .counter {
        margin: 0 auto;
        text-align: center;
    }
}
Enter fullscreen mode Exit fullscreen mode

vite-related settings

Finally, let's configure the necessary settings for building with Vite.

vite.config.ts(build configuration)

Place the vite build configuration file in the root directory. In laravel(), specify the file you want to build. You can put SaSS, TypeScript, or whatever you want.

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
    plugins: [
        vue(),
        laravel([
            'resources/sass/app.scss',
            'resources/js/app.ts',
        ]),
    ],
});

Enter fullscreen mode Exit fullscreen mode

Basically, this is the end of the Vite setup, but for Vuetify, continue below.

TreeShaking with Vuetify

If you bundle Vuetify in its entirety as it is, the post-build file will be large, and to prevent bloat, set up TreeShaking in Vuetify's Vite plugin.
Install the plugin and add it to vute.config.ts.

npm i vite-plugin-vuetify
Enter fullscreen mode Exit fullscreen mode
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
* import vuetify from 'vite-plugin-vuetify'

export default defineConfig({
    plugins: [
        vue(),
+         vuetify({ autoImport: true }),
        laravel([
            'resources/sass/app.scss',
            'resources/js/app.ts',
        ]),
    ],
});
Enter fullscreen mode Exit fullscreen mode

Loading in Blade

Load the built JS file in the Blade, using @vite instead of @mix() in Laravel Mix. Enter the name of the pre-built file in parentheses.
In other sites, you can also load CSS and JS separately as follows.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Laravel 9</title>
    @vite('resources/sass/app.scss')
</head>
<body>
    <div id="app"></div>
    @vite('resources/js/app.ts')
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Also, the Vite plugin is very good, and if you do a Production build, it will give you a random number and do version control on its own.

Build test

## Development build (hot read)
npm run dev
## Build production build
npm run build
Enter fullscreen mode Exit fullscreen mode

If the development build successfully shows the Vuetify component, let's enjoy!

Image description

Top comments (0)