I am using Laravel Mix to compile my JS and CSS assets. I'm currently using .version()
to achieve this.
The problem is that this produces a file similar to:
/css/app.css?id=03def6a69840076e8f29
That works fine when serving it locally, but if I'm using a CDN to serve this content via an origin pull then the query string doesn't force a new pull of the file. Ideally I'd like the following instead:
/css/03def6a69840076e8f29/app.css
Or:
/css/03def6a69840076e8f29.css
Both of these are different files, so it forces a pull on the CDN.
How can this be achieved with Laravel Mix?
I had the same problem, and came up with the solution:
Add the following line to public/.htaccess
:
RewriteRule ^assets/[a-f0-9]+/(.*)$ /$1 [L]
right before RewriteCond %{REQUEST_FILENAME} !-d
this will treat urls like /assets/ab7320d/css/whatever.css
as /css/whatever.css
Put the following code to resources/assets/js/rewriteMixManifest.js
let fs = require('fs')
let mixManifestPath = `${process.cwd()}/public/mix-manifest.json`
let mixFileContents = fs.readFileSync(mixManifestPath)
let oldMapping = JSON.parse(mixFileContents)
function updateMapping(path) {
if(path.indexOf("?") < 1) {
return path
}
let [filename, idPart] = path.split("?")
let [_, id] = idPart.split("=")
return `/assets/${id}${filename}`
}
let newContent = {}
for(let file in oldMapping) {
newContent[file] = updateMapping(oldMapping[file])
}
console.log("Manifest rewritten.")
fs.writeFileSync(mixManifestPath, JSON.stringify(newContent, null, 2))
In package.json
, add the following line in scripts
(just like "dev" key)
"rewrite-manifest": "node resources/assets/js/rewriteMixManifest.js",
After each build (e.g. npm run production
) also run npm run rewrite-manifest
So what public/mix-manifest.json
file does is it maps each assets file (for {{ mix('css/app.css') }}
) to some string that will actually go to HTML. My script rewrites the string to put version not to query string, but to the path. .htaccess
makes sure the path is interpreted right.
The path structure is of course up to you to change to your liking
For me it solved the problem with Google Cloud CDN, hope it helps you too