javascriptwebpackimagemin

How to minimize only changed images with imagemin-webpack-plugin?


Im using imagemin-webpack-plugin to minimize images in my project. It only runs when I run npm build. But, each time i do that, it minimizes all the images over again, which is unnecessary. So, I want for it to just minimize the images that were changed. I've done it with gulp before but I'm new to webpack so I'm not really sure what to do.

Also, when I started using this plugin, I noticed that when I added a new image while I was developing, it wouldn't show up until I ran the build command. Not sure why that is, might be an unrelated problem...

const merge = require("webpack-merge");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

const common = require("./webpack.common.js");

const imageminMozjpeg = require('imagemin-mozjpeg');
const CopyWebpackPlugin = require('copy-webpack-plugin');
var ImageminPlugin = require('imagemin-webpack-plugin').default


module.exports = merge(common, {
  mode: "production",

  output: {
    filename: "[name].[hash:5].js",
    chunkFilename: "[id].[hash:5].css"
  },

  plugins: [
    new CopyWebpackPlugin([{
      from: 'src/images/',
      to: 'images/'
    }]),
    new ImageminPlugin({ 
      test: /\.(jpe?g|png|gif|svg)$/i,
        pngquant: ({quality: 80}),
        plugins: [imageminMozjpeg({quality: 50})]
    })
  ]
});

Solution

  • As of writing, you can use cacheFolder option for the plugin.

    https://github.com/Klathmon/imagemin-webpack-plugin#optionscachefolder

    new ImageminPlugin({
      cacheFolder: './.cache',
      // ...
    })
    

    Additionally you do not need to use CopyWebpackPlugin plugin, I find it redundant when the Imagemin plugin already has this in-built.

    https://github.com/Klathmon/imagemin-webpack-plugin#optionsexternalimages

    new ImageminPlugin({
      externalImages: {
        context: '.',
        sources: glob.sync('./src/images/**/*.{jpg,png}'),
        destination: 'images',
        fileName: '[path][name].[ext]'
      }
      // ...
    })