Serve Vue3 applications using Laravel Valet
As many of you may know, if you're on a Mac, you can use Laravel Valet to quickly serve Laravel applications using the directory name as the hostname.
Now, I'm not in the business of wasting your time, so I'll say this from the start: this solution will not work with hot module replacement; it only works with a production bundle. However, the good news is we can still watch for changes and automatically trigger rebuilds.
Anyway, here's how you can do it.
The first thing you need to do is create a custom Laravel Valet driver. ~/.config/valet/Drivers/SampleValetDriver.php
provides a great starting point, so duplicate that file to Vue3ValetDriver.php
, open it, and make the following changes.
<?php
class Vue3ValetDriver extends ValetDriver
{
public function serves($sitePath, $siteName, $uri)
{
return file_exists($sitePath.'/vite.config.js') && file_exists($sitePath.'/index.html');
}
public function isStaticFile($sitePath, $siteName, $uri)
{
if (file_exists($staticFilePath = $sitePath.'/dist/'.$uri)) {
return $staticFilePath;
}
return false;
}
public function frontControllerPath($sitePath, $siteName, $uri)
{
return $sitePath.'/dist/index.html';
}
}
The serves
function determines whether or not the directory is a Vue3 application. It does that by checking the presence of the vite.config.js
and index.html
files. If both files are present, Valet will serve the directory using this new driver.
The isStaticFile
determines if the incoming request is for a static file from the dist/
directory, and if it is, it returns a full path to it.
Finally, the frontControllerPath
points to the entry file of our application, which for a Vue3 app is /dist/index.html
.
Once you save the new driver, you need to make sure Laravel Valet serves the Vue3 application. You can move the Vue3 app inside a parked directory or run the valet link project-name
command.
If you visit project-name.test
and you get an error saying "Failed opening required... bla bla bla, /dist/index.html", that's because your Vue3 project doesn't have a production bundle yet (/dist
directory). So create one using npm run build
, refresh the page, and you should see your Vue3 app.
However, if you are to make some changes and hit save, the changes won't be reflected in the browser - even if you refresh the page.
You can't just run npm run dev
because this won't update the dist
directory with a new bundle; only npm run build
does that. But then again, manually running npm run build
every time we make a change doesn't sound that great either.
What you can do is create a new build-watch
script that runs vite build
but with a --watch
flag included. This will make it so vite rebuilds the /dist
directory every time you make changes to your application.
"build-watch": "vite build --watch"
Now you can run the new command npm run build-watch
, and if you make a change, save, and refresh, the browser will reflect your changes.
PS: If you find a way to do this with HMR, please let me know!