After banging my head against it the whole of yesterday and today, I
got figured out how to still use it with a blade file.
This is more a hack/workaround until it is better supported, but works
at my end. The goal is to still use my index.blade.html which has the
<meta name="csrf-token" content="{{ csrf_token() }}">
inside,
because I still need to use it until I build my authentication with
Vue. Also I wanted to get a HMRis beheavior work, so I could still use
yarn serve
while developing instead of having to rerun yarn build
everytime I change anything. For this we will create our own vuemix
helper to replace laravel-mix mix()
in our .blade.html files. I used
best practices described
here
for this.
So without further ado:
We need to create 2 new files:
- /bootstrap/helpers.php
- /frontend/hmr/hot
helper.php: this file adds a new laravel/blade/php helper vuemix()
which we will use in our blade file instead of mix()
```
if (! function_exists('vuemix')) {
/**
* Get the path to a versioned Mix file.
*
* @param string $path
* @param string $manifestDirectory
* @return \Illuminate\Support\HtmlString|string
*
* @throws \Exception
*/
function vuemix($path, $manifestDirectory = '')
{
if (! Str::startsWith($path, '/')) {
$path = "/{$path}";
}
// check if HMR server is running via helper file 'hot'
if (file_exists(public_path($manifestDirectory.'/hot'))) {
$url = file_get_contents(public_path($manifestDirectory.'/hot'));
$main = '/app.js'; // only use this as path, because css, etc are already packed in HMR mode
if (Str::startsWith($url, ['http://', 'https://'])) {
return new HtmlString(Str::after($url, ':').$main);
}
return new HtmlString('//localhost:8080'.$main);
}
return new HtmlString($path); // return path without changing anything aka production
} } ```
after we have to also add our new "helpers.php" to /composer.json
so
laravel knows to load it:
"autoload": {
...
"files": [
...
"bootstrap/helpers.php"
]
},
with that out of the way, in your index.blade.html
file replace all
occurrences of mix()
e.g.
<body>
<div id="app"> </div><!-- #app -->
<!-- Scripts -->
@stack('before-scripts')
{!! script(mix('js/app.js')) !!}
</body>
with
<body>
<div id="app"> </div><!-- #app -->
<!-- Scripts -->
@stack('before-scripts')
{{script(vuemix('js/app.js'))}}
{{script(vuemix('js/chunk-vendors.js'))}}
</body>
you can do the same with your css files, it will then load app.js for
it, since yarn serve
seems to pack the css into the livereload
app.js.
VERY IMPORTANT
one detailed which took me forever: if you are coming from
laravel-mix
you probably only link your app.js
and you are done.
but here you also have to link chunk-vendors.js
, which for some
reason get's splitted and I can't turn off, because it's a feature. so
if you only had 1 line of linked JS, you now need two.
Almost done. Now we just have to edit your package.json
and
vue.config.json
so it creates and temporary hot
file when yarn
serve
is started and also doesn't overwrite your index.php and
creates your js files without version hashes when you use yarn
build
. because we have linked them above directly without these
hashed. the hot
file modus operanti I got from laravel-mix
as a
way to figure out if we are using yarn serve
or yarn build
. don't
hit me for it, I told you it's hackish ;)
package.json: edit this scripts, to copy and remove our hot
file "scripts": {
"serve": "cp ./hmr/hot ../public/ && vue-cli-service serve",
"build": "rm -rf ../public/{js,css,img,hot} && vue-cli-service build --no-clean", }
pay attention to hot on the build line,
it looks almost the same then the original line.
now create /frontend/hmr/hot
and fill it with this:
http://localhost:8080/
now vue.config.json
add this lines, from vue-cli
documentation:
//// Disable Index.html Generation // disable hashes in
filenames filenameHashing: false, // delete HTML related webpack
plugins chainWebpack: config => {
if (process.env.NODE_ENV === "production") {
config.plugins.delete('html')
config.plugins.delete('preload')
config.plugins.delete('prefetch')
} },
you can also edit indexPath
back, since index isn't generated
anymore while building: // modify the location of the generated
HTML file. // make sure to do this only in production. indexPath:
"index.html",
And with this it should now be possible to use yarn serve
and yarn
build
with a "classical" laravel blade setup.