Moving A Laravel Webpack Project To Vite
Tags: webpack, javascript, laravel, vite
Published: 2022-07-06 02:58:36


[Vite](https://vitejs.dev/) is the `Next Generation Frontend Tooling,` which is Laravel's default from now on.

[Vite](https://vitejs.dev/) is a build tool created by Evan You (creator of Vue) which utilizes the availability of native ES modules in the browser.

### Features Of Vite

-   Instant Server Start
    
-   Lightning Fast HMR (Hot Module Replacement)
    
-   Optimized Build
    
-   Universal Plugins
    
-   Fully Typed APIs
    
-   [View More Features](https://vitejs.dev/guide/features.html)
    

The [Laravel documentation](https://laravel.com/docs/9.x/vite) contains an entire section explaining how it works and how to use it. But most of us are more interested in using it in an `existing project.` So that's what this post is for.

## Why Vite

Before switching to a new tool, it is a good idea to think about `why` you want to do that. It is already enough for me to be Laravel's new default front-end bundling, but let's also talk about some details.

The main benefit is the `overall improved performance.` Vite is faster in starting a new dev server, bundling assets, and updating them than other tools like webpack.

Vite is leveraging new advancements in the ecosystem, like the availability of native ES modules in the browser and the rise of JavaScript tools written in compile-to-native languages. There is a detailed explanation in the [Why Vite](https://vitejs.dev/guide/why.html) section of the official docs.

### Update Laravel Framework

To make use of the new Vite integration, you will need to update to at least version `9.19.0` of the `laravel/framework`:

```bash
composer require laravel/framework:^9.19.0
```

### Install Vite and the Laravel Plugin

First, you will need to install [Vite](https://vitejs.dev/) and the [Laravel Vite Plugin](https://www.npmjs.com/package/laravel-vite-plugin) using your npm package manager of choice:

```bash
npm install --save-dev vite laravel-vite-plugin
```

You may also need to install additional Vite plugins for your project, such as the Vue or React plugins:

```bash
npm install --save-dev @vitejs/plugin-vue
```

```bash
npm install --save-dev @vitejs/plugin-react
```

Also, the `scripts` section of our `package.json` the file will change due to the new Vite scripts.

```json
"scripts": {
    "dev": "vite",
    "build": "vite build"
},
```

That's all we need for the scripts.

Since Vite is a replacement for webpack, we can remove the `laravel-mix` dependency and delete the `webpack.mix.js` file from our application.

```bash
npm remove laravel-mix && rm webpack.mix.js
```

Your `package.json` the file will now look something like this:

```json
{
    "private": true,
    "scripts": {
        "dev": "vite",
        "build": "vite build"
    },
    "devDependencies": {
        "axios": "^0.25",
        "laravel-vite-plugin": "^0.2.1",
        "lodash": "^4.17.19",
        "postcss": "^8.4.14",
        "postcss-import": "^14.0.1",
        "vite": "^2.9.11",
    }
}
```

## Vite Configuration

Now we need to set up Vite. Therefore create a new `vite.config.js` file in the root of your Laravel application.

```javascript
import laravel from 'laravel-vite-plugin'
import {defineConfig} from 'vite'

export default defineConfig({
    plugins: [
        laravel([
            'resources/css/app.css',
            'resources/js/app.js',
        ]),
    ],
});
```

This is where we use the `vite` and `laravel-vite-plugin` packages, and we also define our asset paths.

### Configure Vite

Create a `vite.config.js` file in the root of your project:

```javascript
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';

export default defineConfig({
    plugins: [
        laravel([
            'resources/css/app.css',
            'resources/js/app.js',
        ]),
    ],
});
```

## Using Vite In Your Templates

In the `head` of your template files, we have to load the assets through the new `@vite` blade directive.

```html
@vite(['resources/css/app.css', 'resources/js/app.js'])
```

You don't need to use `mix` or load them manually anymore.

#### Update Aliases

If you are migrating aliases from your `webpack.mix.js` file to your `vite.config.js` file, you should ensure that the paths start with `/`. For example, `resources/js` would become `/resources/js`:

```javascript
export default defineConfig({
    plugins: [
        laravel([
            'resources/css/app.css',
            'resources/js/app.js',
        ]),
    ],
    resolve: {
        alias: {
            '@': '/resources/js'
        }
    }
});
```

For your convenience, the Laravel Vite plugin automatically adds an `@` alias for your `/resources/js` directory. If you do not need to customize your aliases, you may omit this section from your `vite.config.js` file.

**Read Also:** [How to Install Font Awesome with Laravel Mix](https://techvblogs.com/blog/install-font-awesome-laravel-mix)

## Running Vite

To run Vite, you use the npm script `npm run dev,` which we have defined, which is just an alias for `npm run vite.`

It will compile your assets lighting fast! To make your assets production-ready, you can use the new `npm run build` script to version and bundle your assets.

In the background, Vite is using the new assets compiled to the `public/build` directory. This means we can delete the old asset folders, `public/css` and `public/js,` in my case.

## Importing JS Modules Might Change For You

Vite only supports ES modules, so `require` doesn't work anymore, and you need to `import` modules now in your scripts.

Example - not working with Vite anymore:

```javascript
require('package');
```

Example - working with Vite:

```javascript
import myPackage from 'my-package';
```

## Environment Variables

You can inject environment variables to JavaScript through your `.env` file, by prefixing them with `VITE_`.

For example, the given Laravel `Pusher` variables are no longer of use to you.

```
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
```

If you like to use them in JavaScript, rename them.

```
VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
```

### Configure Tailwind

If you are using Tailwind, perhaps with one of Laravel's starter kits, you will need to create a `postcss.config.js` file. Tailwind can generate this for you automatically:

```bash
npx tailwindcss init -p
```

Or, you can create it manually:

```javascript
module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
}
```

If you are using other PostCSS plugins, such as `postcss-import`, you will need to include them in your configuration.

## Auto-Refresh Templates On Change

One of Vite's most prominent features is `Hot Module Replacement` for Vue.js and React.

But it's also great for refreshing a browser after file changes. By default, this is not working with `Blade` files, but [Freek and Spatie](https://freek.dev/2277-using-laravel-vite-to-automatically-refresh-your-browser-when-changing-a-blade-file) got a working solution.

Just update your Vite configuration with a custom plugin named `blade` here:

```javascript
import laravel from 'laravel-vite-plugin'
import {defineConfig} from 'vite'

export default defineConfig({
    plugins: [
        laravel([
            'resources/css/app.css',
            'resources/js/app.js',
        ]),
        {
            name: 'blade',
            handleHotUpdate({ file, server }) {
                if (file.endsWith('.blade.php')) {
                    server.ws.send({
                        type: 'full-reload',
                        path: '*',
                    });
                }
            },
        }
    ],
});
```

**Thank you** for reading this blog.