Laravel-mix: imagemin

Created on 15 Sep 2017  ยท  12Comments  ยท  Source: JeffreyWay/laravel-mix

Hello,

there is information that image optimization is already in place.
But I can't find any word in documentation about it...

Can you please point me in the right direction?

Thank you

Most helpful comment

@huglester I'll share what worked for me, have images that reduce it to half its normal size or more.

package.json

"devDependencies": {
    "copy-webpack-plugin": "^4.0.1",
    "imagemin-mozjpeg": "^6.0.0",
    "imagemin-webpack-plugin": "^1.4.4",
  }

on webpack.mix.js:

//Third party packages
const ImageminPlugin     = require('imagemin-webpack-plugin').default;
const CopyWebpackPlugin  = require('copy-webpack-plugin');
const imageminMozjpeg    = require('imagemin-mozjpeg');

//Only in production, you can remove if you want to use "npm run dev"
if(mix.inProduction()) {
    mix.webpackConfig({
        plugins: [
            //Compress images
            new CopyWebpackPlugin([{
                from: 'resources/assets/images', // FROM
                to: 'images/', // TO
            }]),
            new ImageminPlugin({
                test: /\.(jpe?g|png|gif|svg)$/i,
                pngquant: {
                    quality: '65-80'
                },
                plugins: [
                    imageminMozjpeg({
                        quality: 65,
                        //Set the maximum memory to use in kbytes
                        maxmemory: 1000 * 512
                    })
                ]
            })
        ],
    });
}

Test and return with the result whether it worked or not. :metal:

All 12 comments

You can do this in your webpack.mix.js file. See: https://github.com/thetalecrafter/img-loader#options

mix.options({
    imgLoaderOptions: {
        enabled: true,
        gifsicle: {},
        mozjpeg: {},
        optipng: {},
        svgo: {},
    }
})

@huglester Did you get it to work? I am also uncertain of its use...

It should happen automatically for any images required by webpack. You don't need to do anything.

@JeffreyWay I don't get it anyway, when it does compress those images?

I have this: mix.copy('resources/assets/template/img', 'public/assets/img');
but both files are the same size

โฏ ls -la resources/assets/template/img/card1.png                                                                                                                                              
-rw-r--r--  1 huglester  staff  2092 Sep 20 19:13 resources/assets/template/img/card1.png
โฏ ls -la public/assets/img/card1.png                                                                                                                                                      
-rw-r--r--  1 huglester  staff  2092 Sep 30 03:27 public/assets/img/card1.png

@huglester I'll share what worked for me, have images that reduce it to half its normal size or more.

package.json

"devDependencies": {
    "copy-webpack-plugin": "^4.0.1",
    "imagemin-mozjpeg": "^6.0.0",
    "imagemin-webpack-plugin": "^1.4.4",
  }

on webpack.mix.js:

//Third party packages
const ImageminPlugin     = require('imagemin-webpack-plugin').default;
const CopyWebpackPlugin  = require('copy-webpack-plugin');
const imageminMozjpeg    = require('imagemin-mozjpeg');

//Only in production, you can remove if you want to use "npm run dev"
if(mix.inProduction()) {
    mix.webpackConfig({
        plugins: [
            //Compress images
            new CopyWebpackPlugin([{
                from: 'resources/assets/images', // FROM
                to: 'images/', // TO
            }]),
            new ImageminPlugin({
                test: /\.(jpe?g|png|gif|svg)$/i,
                pngquant: {
                    quality: '65-80'
                },
                plugins: [
                    imageminMozjpeg({
                        quality: 65,
                        //Set the maximum memory to use in kbytes
                        maxmemory: 1000 * 512
                    })
                ]
            })
        ],
    });
}

Test and return with the result whether it worked or not. :metal:

@marcelogarbin thank you very much.
Indeed this one worked :)

@marcelogarbin Thanks for the solution, but I figured out a downside that if we copy and compress images via CopyWebpackPlugin and ImageminPlugin, those image filenames won't be included into mix-manifest.json when calling mix.version(); Which means we may not take the advantage of cache-busting feature from laravel-mix.

@marcelogarbin @ajhsu did you ever get this to work with versioning?

@ArondeParon No, I wrote a independent script for image compression instead.

I still took the advantage of mix.copy within webpack.mix.js like:
mix.copy('resources/images/*.{jpg,jpeg,png,gif,svg,ico}', 'public/assets/images')

Then I hooked a custom script to run image compression (which will compress image files in place) after it.

I wouldn't say it's the best solution, but it works for me.

@ArondeParon Honestly, I had abandoned that question.

I didn't modify anything I had posted before (https://github.com/JeffreyWay/laravel-mix/issues/1192#issuecomment-333307250). However I added the following command at the end of webpack.mix.js mix.version(); and mix.version('public/images'); and it looks like it worked, because all the images in this folder were versioned in the file mix-manifest.json.

However I had to run the npm run prod command twice.

I didn't do other tests, I would have to test more often. I do not know @JeffreyWay position on that.

Check it and return.

@marcelogarbin you can prevent the double run of npm run prod by adding this at the bottom of your mix file (instead of two lines containing mix.version):

mix.version(['public/images']);

The mix.version() will automatically version any compiled JavaScript, Sass/Less, or combined files. However, if you'd also like to version extra files as part of your build, simply pass a path, or array of paths, to the method, like so:
see https://github.com/JeffreyWay/laravel-mix/blob/v2.1/docs/versioning.md

You could do this, since the imgLoaderOptions is passed directly to the img-loader.

``js // Image loader options. mix.options({ imgLoaderOptions: { plugins: [ require('imagemin-gifsicle')({ interlaced: false }), require('imagemin-mozjpeg')({ progressive: true, arithmetic: false }), require('imagemin-pngquant')({ floyd: 0.5, speed: 2, quality: [0.6, 0.8] }), ] } });

Was this page helpful?
0 / 5 - 0 ratings

Related issues

amin101 picture amin101  ยท  3Comments

stefensuhat picture stefensuhat  ยท  3Comments

jpmurray picture jpmurray  ยท  3Comments

pixieaka picture pixieaka  ยท  3Comments

sdebacker picture sdebacker  ยท  3Comments