Starter Template of Laravel+Vite+Vuetify3+TypeScript+Router+Sass
Tags: webdev, vue, javascript, php
Published: 2023-03-13 17:41:33

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.

{% embed https://github.com/ichii731/laravel9-vite-vuetify3-starter %}


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g61bcliy9x42rb6yx31l.png)



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


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wxq4rtz2yz94vh9a00pv.png)


## Manually Setup
### Laravel+Vite

```bash
composer create-project --prefer-dist laravel/laravel:^9.x *********
```

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.


```bash
npm i
```

### 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

``` bash
npm i @vitejs/plugin-vue vue
```

```
npm i vuetify@next vue-router
```

### (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](https://sebastiandedeyne.com/vite-with-laravel/typescript/)

Also, for Sass, install a transpiler.

```bash
npm i sass -D
```

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

```typescript
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')

```

### 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**.

```vue
<template>
  <v-container class="counter">
  <!-- class="container" is added to check Sass behavior. -->
    <router-view></router-view>
  </v-container>
</template>
```

```typescript
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;
```

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

```vue
<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>
```

### create Sass file

```sass
#app {
    .counter {
        margin: 0 auto;
        text-align: center;
    }
}
```

### 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**.

```typescript
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',
        ]),
    ],
});

```

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`.

```bash
npm i vite-plugin-vuetify
```

```typescript
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',
        ]),
    ],
});
```

### 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.

```html
<!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>
```

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
```bash
## Development build (hot read)
npm run dev
## Build production build
npm run build
```
If the development build successfully shows the Vuetify component, let's enjoy!

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/67mwldoivjlrbynegevx.png)