Migrating a Laravel Jetstream app from Mix/Webpack to Vite
February 23, 2022 (2y ago)
For months I've been frustrated with how slow Laravel Mix (Webpack) was to compile, even on a beefy M1 Max or Ryzen machine, yet current guides for migrating to Vite were unhelpful to me. Every time I'd migrate, get stuck, revert back, and repeat the process.
Before I begin, I want to give a huge shoutout to Matt for sparing some time to help me with this, we worked together on a call this morning to migrate my newest project Analyse. If you're not already, go give Matt a follow, he shares really awesome Laravel tips - in addition to sharing his progress on a sweet new developer platform.
Speed Comparison
Locally on an M1 Max, I went from ~3 seconds with Mix down to 120 milliseconds with Vite during development. On our Ryzen production machine, this came down from 10 seconds to 5 seconds, such a crazy difference when pushing to production often.
Requirements
I want to mention that this is an opinionated guide, by this I mean that the following are used:
Vue 3
Inertia.js
Laravel Jetstream
TailwindCSS v3
Inertia Global/Persistant Layouts
I can't comment on other set-ups, but this is what we are using within Analyse, and wanted to share in case it helps others.
Migration
First head to package.json, as you'll need to run the following to install the dependencies needed:
Then, you'll need to add the following:
After you've made these changes, rename your tailwindcss.config.js file to tailwind.cjs.
Next, you'll need to create a new vite.client.config.js file within the root of your project:
Then you'll want to replace the following tags:
The new change tells Laravel where our assets will be, and for development we'll be using our live server instead.
After you've made these changes, we will need to change our bootstrap file to use imports instead:
Then head to your app.js file and modify your file to look similar to this:
So what are we doing here?
Globally define the Inertia Head and Link (optional)
Added the asyncViews variable.
Changing all require to use import.
Adding our globalProperties for Ziggy.
Importing our stylesheet.
The final and most important change left is to ensure each component imported has a .vue suffix, for example:
Without making this change, your components or layout will not load, and I spent ages debugging being unsure why.
Finally, it's time to delete any remaining webpack files and dependencies, like so:
Server-Side Rendering (SSR) Support
If search traffic is your main source of visitors, then you'll need SSR to be able to load the first page from the server. Thankfully, Inertia.js makes this fairly easy by providing us with a built-in server, we just need to configure Vite in SSR mode.
To do this, we first need to install the following packages:
Once you have installed these, we need to create our SSR vite file for serving assets from our server:
As you can see, this file is very similar to our vite.client.config.js file, except we are optimising this to be ran off a server instead.
Next we need to create an ssr.js file within the resources/js folder for compiling our assets:
After you've created this file, we will need to enable support for utilising Ziggy within our SSR environment. To this, create a useRoute.ts file within the resources/js/Composable folder with the following content:
A huge shout-out to Bruno Tomé for building and sharing this code snippet - it is a huge factor in making Ziggy with SSR possible.
Now we need to configure our Inertia server, to do that we first need to add the following to our app.blade.php file:
Then head to your package.json file, as we need to add our SSR scripts:
Now we need to configure our Inertia SSR server, so lets publish our inertia.php file:
This inertia.php file will be created in the config/ directory, we need to enable SSR like so:
Now, when testing locally you can run the following in separate windows:
npm run dev
npm run ssr-dev
npm run start-ssr
When you're ready to go to production, you'd run the following on your production machine:
If you don't already have PM2, install it by doing the following:
This allows us to keep our SSR server alive, which we can start by running:
That's it! You now have SSR running for your Laravel + Inertia + Vue + Vite application ☺️
You're done! You've now moved from Webpack to Vite, and should see a massive speed difference. 🎉