mikevrind's avatar

Image versioning with Laravel Mix

I would like to use Mix in a bit of a different setup than as provided 'out of the box'. Instead of a hash added as a query string to the js/css I would like to have my assets 'build' in a separate (hashed) folder.

The reason I'm looking into this solution is to provide a way to apply caching/cache busting for images. Maybe there is a better solution but I can not find a way to apply versioning on images with Laravel Mix.

Is there a way to implement this behaviour or maybe manipulate the content of the mix-manifest file?

0 likes
3 replies
mikevrind's avatar

Got something going;

const mix = require('laravel-mix');
const md5 = require('md5');
const fs = require('file-system');
const _ = require('lodash');
const jsonfile = require('jsonfile');

const hash = md5(Date.now());
const buildFolder = 'public/build/' + hash;
const mixManifest = './mix-manifest.json';

// Clear the build directory, no need to keep old builds
fs.rmdirSync('public/build/');

mix
    .setPublicPath('./')
    .scripts(['resources/js/js1.js', 'resources/js/js2.js'], buildFolder + '/js/app.js')
    .styles(['resources/css/html.css', 'resources/css/body.css'], buildFolder + '/css/app.css')
    .copyDirectory('resources/images', buildFolder + '/images')
    .then(function () {
        jsonfile.readFile(mixManifest, function (err, obj) {
            const newJson = {};
            let _hash = '';
            _.forIn(obj, function (value, key) {

                // Add the hash to the manifest which could be used to resolve paths for images/documents etc.
                if ( _hash === '' ){
                    newJson['_hash'] = hash;
                    _hash = hash;
                }

                key = key.replace('/'+buildFolder+'/', '');

                newJson[key] = value;
            });
            jsonfile.writeFile(mixManifest, newJson, {spaces: 4}, function (err) {
                if (err) console.error(err);
            });
        });
    });

Results in the following manifest:

{
    "_hash": "bb5caa8db4f702997d8afc500307001b",
    "js/app.js": "/public/build/bb5caa8db4f702997d8afc500307001b/js/app.js",
    "css/app.css": "/public/build/bb5caa8db4f702997d8afc500307001b/css/app.css"
}

The images are still missing from the manifest file. This could be resolved by adding them into the version(['img1', 'img2']) method. I use the _hash property from the manifest to resolve the path to other resources like images and documents.

I don't know if there is an easy method to add all static resources like images and document to the version method. I don't want to manually keep a list of these files. If I'm correct, the version method expects en array of files.

Please or to participate in this conversation.