Coder Social home page Coder Social logo

webpack-contrib / image-minimizer-webpack-plugin Goto Github PK

View Code? Open in Web Editor NEW
228.0 16.0 36.0 10.1 MB

Webpack loader and plugin to compress images using imagemin

License: MIT License

JavaScript 100.00%
imagemin webpack webpack-loader webpack-plugin loader image-optimization

image-minimizer-webpack-plugin's Introduction

Imagemin Webpack

Plugin and Loader for webpack to optimize (compress) all images using imagemin. Do not worry about size of images, now they are always optimized/compressed.

npm node tests cover discussion size

image-minimizer-webpack-plugin

Getting Started

This plugin can use 4 tools to optimize/generate images:

  • imagemin - optimize your images by default, since it is stable and works with all types of images
  • DEPRECATED squoosh - while working in experimental mode with .jpg, .jpeg, .png, .webp, .avif file types.
  • sharp - High performance Node.js image processing, the fastest module to resize and compress JPEG, PNG, WebP, AVIF and TIFF images. Uses the libvips library.
  • svgo - tool for optimizing SVG vector graphics files. Supports only SVG files minification.

Warning

By default we don't install anything

Install optimize/generate tool

To begin, you'll need to install image-minimizer-webpack-plugin and image minimizer/generator:

npm install image-minimizer-webpack-plugin imagemin --save-dev

Warning

imagemin uses plugin to optimize/generate images, so you need to install them too

npm install image-minimizer-webpack-plugin @squoosh/lib --save-dev
npm install image-minimizer-webpack-plugin sharp --save-dev
npm install image-minimizer-webpack-plugin svgo --save-dev

Images can be optimized in two modes:

  1. Lossless (without loss of quality).
  2. Lossy (with loss of quality).

Optimize with imagemin

Note

Explore the options to get the best result for you.

Recommended imagemin plugins for lossless optimization

npm install imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo --save-dev

Recommended imagemin plugins for lossy optimization

npm install imagemin-gifsicle imagemin-mozjpeg imagemin-pngquant imagemin-svgo --save-dev

For imagemin-svgo v9.0.0+ need use svgo configuration

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  module: {
    rules: [
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        type: "asset",
      },
    ],
  },
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.imageminMinify,
          options: {
            // Lossless optimization with custom option
            // Feel free to experiment with options for better result for you
            plugins: [
              ["gifsicle", { interlaced: true }],
              ["jpegtran", { progressive: true }],
              ["optipng", { optimizationLevel: 5 }],
              // Svgo configuration here https://github.com/svg/svgo#configuration
              [
                "svgo",
                {
                  plugins: [
                    {
                      name: "preset-default",
                      params: {
                        overrides: {
                          removeViewBox: false,
                          addAttributesToSVGElement: {
                            params: {
                              attributes: [
                                { xmlns: "http://www.w3.org/2000/svg" },
                              ],
                            },
                          },
                        },
                      },
                    },
                  ],
                },
              ],
            ],
          },
        },
      }),
    ],
  },
};

DEPRECATED Optimize with squoosh

npm install @squoosh/lib --save-dev

Recommended @squoosh/lib options for lossy optimization

For lossy optimization we recommend using the default settings of @squoosh/lib package. The default values and supported file types for each option can be found in the codecs.ts file under codecs.

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  module: {
    rules: [
      // You need this, if you are using `import file from "file.ext"`, for `new URL(...)` syntax you don't need it
      {
        test: /\.(jpe?g|png)$/i,
        type: "asset",
      },
    ],
  },
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.squooshMinify,
          options: {
            // Your options for `squoosh`
          },
        },
      }),
    ],
  },
};

Recommended squoosh options for lossless optimization

For lossless optimization we recommend using the options listed below in minimizer.options.encodeOptions.

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  module: {
    rules: [
      // You need this, if you are using `import file from "file.ext"`, for `new URL(...)` syntax you don't need it
      {
        test: /\.(jpe?g|png)$/i,
        type: "asset",
      },
    ],
  },
  optimization: {
    minimizer: [
      new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.squooshMinify,
          options: {
            encodeOptions: {
              mozjpeg: {
                // That setting might be close to lossless, but it’s not guaranteed
                // https://github.com/GoogleChromeLabs/squoosh/issues/85
                quality: 100,
              },
              webp: {
                lossless: 1,
              },
              avif: {
                // https://github.com/GoogleChromeLabs/squoosh/blob/dev/codecs/avif/enc/README.md
                cqLevel: 0,
              },
            },
          },
        },
      }),
    ],
  },
};

Optimize with sharp

npm install sharp --save-dev

Recommended sharp options for lossy optimization

For lossy optimization we recommend using the default settings of sharp package. The default values and supported file types for each option can be found in the sharp documentation.

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  module: {
    rules: [
      // You need this, if you are using `import file from "file.ext"`, for `new URL(...)` syntax you don't need it
      {
        test: /\.(jpe?g|png)$/i,
        type: "asset",
      },
    ],
  },
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.sharpMinify,
          options: {
            encodeOptions: {
              // Your options for `sharp`
              // https://sharp.pixelplumbing.com/api-output
            },
          },
        },
      }),
    ],
  },
};

Recommended sharp options for lossless optimization

For lossless optimization we recommend using the options listed below in minimizer.options.encodeOptions.

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  module: {
    rules: [
      // You need this, if you are using `import file from "file.ext"`, for `new URL(...)` syntax you don't need it
      {
        test: /\.(jpe?g|png)$/i,
        type: "asset",
      },
    ],
  },
  optimization: {
    minimizer: [
      new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.sharpMinify,
          options: {
            encodeOptions: {
              jpeg: {
                // https://sharp.pixelplumbing.com/api-output#jpeg
                quality: 100,
              },
              webp: {
                // https://sharp.pixelplumbing.com/api-output#webp
                lossless: true,
              },
              avif: {
                // https://sharp.pixelplumbing.com/api-output#avif
                lossless: true,
              },

              // png by default sets the quality to 100%, which is same as lossless
              // https://sharp.pixelplumbing.com/api-output#png
              png: {},

              // gif does not support lossless compression at all
              // https://sharp.pixelplumbing.com/api-output#gif
              gif: {},
            },
          },
        },
      }),
    ],
  },
};

Optimize with svgo

npm install svgo --save-dev

Recommended svgo options for optimization

For optimization we recommend using the options listed below in minimizer.options.encodeOptions. The default values for plugins can be found in the svgo plugins source code.

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  module: {
    rules: [
      // You need this, if you are using `import file from "file.ext"`, for `new URL(...)` syntax you don't need it
      {
        test: /\.(svg)$/i,
        type: "asset",
      },
    ],
  },
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.svgoMinify,
          options: {
            encodeOptions: {
              // Pass over SVGs multiple times to ensure all optimizations are applied. False by default
              multipass: true,
              plugins: [
                // set of built-in plugins enabled by default
                // see: https://github.com/svg/svgo#default-preset
                "preset-default",
              ],
            },
          },
        },
      }),
    ],
  },
};

Advanced setup

If you want to use loader or plugin standalone see sections below, but this is not recommended.

By default, plugin configures loader (please use the loader option if you want to disable this behaviour), therefore you should not setup standalone loader when you use a plugin setup.

Loader optimizes or generates images using options, so inlined images via data URI (i.e. data:) will be optimized or generated too, not inlined images will be optimized too.

Query Parameters (only squoosh and sharp currently)

The plugin supports the following query parameters:

  • width/w - allows you to set the image width
  • height/h - allows you to set the image height
  • as - to specify the preset option

Examples:

const myImage1 = new URL("image.png?width=150&height=120", import.meta.url);
const myImage2 = new URL("image.png?w=150&h=120", import.meta.url);
// You can omit one of the parameters to auto-scale
const myImage3 = new URL("image.png?w=150", import.meta.url);
// It works with the `preset` query parameter
const myImage4 = new URL("image.png?as=webp&w=150&h=120", import.meta.url);
// You can use `auto` to reset `width` or `height` from the `preset` option
const myImage5 = new URL("image.png?as=webp&w=150&h=auto", import.meta.url);
.class {
  background: url("./image.png?width=150&height=120");
}
<picture>
  <source srcset="photo.jpg?as=avif&width=150&height=120" type="image/avif" />
  <source srcset="photo.jpg?as=webp&width=150&height=120" type="image/webp" />
  <img src="photo.jpg?width=150&height=120" alt="photo" />
</picture>

NOTE: you need to setup avif and webp presets, example for webp

Standalone Loader

Documentation: Using loaders.

In your webpack.config.js, add the ImageMinimizerPlugin.loader and specify the asset modules options (if you use images in import):

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  module: {
    rules: [
      // You need this, if you are using `import file from "file.ext"`, for `new URL(...)` syntax you don't need it
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        type: "asset",
      },
      // We recommend using only for the "production" mode
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        use: [
          {
            loader: ImageMinimizerPlugin.loader,
            enforce: "pre",
            options: {
              minimizer: {
                implementation: ImageMinimizerPlugin.imageminMinify,
                options: {
                  plugins: [
                    "imagemin-gifsicle",
                    "imagemin-mozjpeg",
                    "imagemin-pngquant",
                    "imagemin-svgo",
                  ],
                },
              },
            },
          },
        ],
      },
    ],
  },
};

Standalone Plugin

Documentation: Using plugins.

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  module: {
    rules: [
      // You need this, if you are using `import file from "file.ext"`, for `new URL(...)` syntax you don't need it
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        type: "asset",
      },
    ],
  },
  optimization: {
    minimizer: [
      // Extend default minimizer, i.e. `terser-webpack-plugin` for JS
      "...",
      // We recommend using only for the "production" mode
      new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.imageminMinify,
          options: {
            plugins: [
              "imagemin-gifsicle",
              "imagemin-mozjpeg",
              "imagemin-pngquant",
              "imagemin-svgo",
            ],
          },
        },
        // Disable `loader`
        loader: false,
      }),
    ],
  },
};

Plugin Options

test

Type:

type test = string | RegExp | Array<string | RegExp>;

Default: /\.(jpe?g\|png\|gif\|tif\|webp\|svg\|avif)\$/i

Test to match files against.

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        test: /\.(jpe?g|png|gif|svg)$/i,
      }),
    ],
  },
};

include

Type:

type include = string | RegExp | Array<string | RegExp>;

Default: undefined

Files to include.

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        include: /\/includes/,
      }),
    ],
  },
};

exclude

Type:

type exclude = string | RegExp | Array<string | RegExp>;

Default: undefined

Files to exclude.

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        exclude: /\/excludes/,
      }),
    ],
  },
};

minimizer

Type:

type minimizer =
  | {
      implementation: (
        original: {
          filename: string;
          data: Buffer;
          warnings: Array<Error>;
          errors: Array<Error>;
          info: import("webpack").AssetInfo;
        },
        options?:
          | {
              [key: string]: any;
            }
          | undefined,
      ) => Promise<{
        filename: string;
        data: Buffer;
        warnings: Array<Error>;
        errors: Array<Error>;
        info: import("webpack").AssetInfo;
      }> & {
        setup?: (() => void) | undefined;
        teardown?: (() => void) | undefined;
      };
      options?:
        | {
            [key: string]: any;
          }
        | undefined;
      filter?: (source: Buffer, sourcePath: string) => boolean | undefined;
      filename?:
        | string
        | ((
            pathData: {
              filename?: string | undefined;
            },
            assetInfo?: import("webpack").AssetInfo | undefined,
          ) => string)
        | undefined;
    }
  | Array<{
      implementation: (
        original: {
          filename: string;
          data: Buffer;
          warnings: Array<Error>;
          errors: Array<Error>;
          info: import("webpack").AssetInfo;
        },
        options?:
          | {
              [key: string]: any;
            }
          | undefined,
      ) => Promise<{
        filename: string;
        data: Buffer;
        warnings: Array<Error>;
        errors: Array<Error>;
        info: import("webpack").AssetInfo;
      }> & {
        setup?: (() => void) | undefined;
        teardown?: (() => void) | undefined;
      };
      options?:
        | {
            [key: string]: any;
          }
        | undefined;
      filter?: (source: Buffer, sourcePath: string) => boolean | undefined;
      filename?:
        | string
        | ((
            pathData: {
              filename?: string | undefined;
            },
            assetInfo?: import("webpack").AssetInfo | undefined,
          ) => string)
        | undefined;
    }>;

Default: undefined

Allows to setup default minify function.

Available minimizers

  • ImageMinimizerPlugin.imageminMinify
  • DEPRECATED ImageMinimizerPlugin.squooshMinify
  • ImageMinimizerPlugin.sharpMinify
  • ImageMinimizerPlugin.svgoMinify

Single minimizer example for imagemin

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        minimizer: {
          // Implementation
          implementation: ImageMinimizerPlugin.imageminMinify,
          // Options
          options: {
            plugins: [
              "imagemin-gifsicle",
              "imagemin-mozjpeg",
              "imagemin-pngquant",
              "imagemin-svgo",
            ],
          },
        },
      }),
    ],
  },
};

More information and examples here.

DEPRECATED Single minimizer example for squoosh

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        minimizer: {
          // Implementation
          implementation: ImageMinimizerPlugin.squooshMinify,
          // Options
          options: {
            encodeOptions: {
              mozjpeg: {
                quality: 90,
              },
            },
          },
        },
      }),
    ],
  },
};

More information and examples here.

Single minimizer example for sharp

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        minimizer: {
          // Implementation
          implementation: ImageMinimizerPlugin.sharpMinify,
          // Options
          options: {
            encodeOptions: {
              jpeg: {
                quality: 90,
              },
            },
          },
        },
      }),
    ],
  },
};

More information and examples here.

Single minimizer example for user defined implementation

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        minimizer: {
          implementation: async (original, options) => {
            const inputExt = path.extname(original.filename).toLowerCase();

            if (inputExt !== ".xxx") {
              // Return `null` if the implementation does not support this file type
              return null;
            }

            let result;

            try {
              result = await minifyAndReturnBuffer(original.data);
            } catch (error) {
              // Store error and return `null` if there was an error
              original.errors.push(error);
              return null;
            }

            return {
              filename: original.filename,
              data: result,
              warnings: [...original.warnings],
              errors: [...original.errors],
              info: {
                ...original.info,
                // Please always set it to prevent double minification
                minimized: true,
                // Optional
                minimizedBy: ["custom-name-of-minimication"],
              },
            };
          },
          options: {
            // Custom options
          },
        },
      }),
    ],
  },
};

Multiple minimizers example

Allows to setup multiple minimizers.

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        minimizer: [
          {
            // `sharp` will handle all bitmap formats (JPG, PNG, GIF, ...)
            implementation: ImageMinimizerPlugin.sharpMinify,

            // exclude SVG if implementation support it. Not required for `sharp`.
            // filter: (source, sourcePath) => !(/\.(svg)$/i.test(sourcePath)),

            options: {
              encodeOptions: {
                // Your options for `sharp`
                // https://sharp.pixelplumbing.com/api-output
              },
            },
          },
          {
            // `svgo` will handle vector images (SVG)
            implementation: ImageMinimizerPlugin.svgoMinify,
            options: {
              encodeOptions: {
                // Pass over SVGs multiple times to ensure all optimizations are applied. False by default
                multipass: true,
                plugins: [
                  // set of built-in plugins enabled by default
                  // see: https://github.com/svg/svgo#default-preset
                  "preset-default",
                ],
              },
            },
          },
        ],
      }),
    ],
  },
};

Minimizer options

implementation

Type:

type implementation = (
  original: {
    filename: string;
    data: Buffer;
    warnings: Array<Error>;
    errors: Array<Error>;
    info: import("webpack").AssetInfo;
  },
  options?: BasicTransformerOptions<T>,
) => Promise<{
  filename: string;
  data: Buffer;
  warnings: Array<Error>;
  errors: Array<Error>;
  info: import("webpack").AssetInfo;
}> & {
  setup?: (() => void) | undefined;
  teardown?: (() => void) | undefined;
};

Default: undefined

Configure the default implementation.

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        minimizer: {
          // Implementation
          implementation: ImageMinimizerPlugin.sharpMinify,
          // Options
          options: {
            encodeOptions: {
              jpeg: {
                quality: 90,
              },
            },
          },
        },
      }),
    ],
  },
};
options

Type:

type options = {
  [key: string]: any;
};

Default: undefined

Options for the implementation option (i.e. options for imagemin/squoosh/sharp/custom implementation).

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.sharpMinify,
          // Options
          options: {
            encodeOptions: {
              jpeg: {
                quality: 90,
              },
            },
          },
        },
      }),
    ],
  },
};
filter

Type:

type filter = (source: Buffer, sourcePath: string) => boolean | undefined;

Default: () => true

Allows filtering of images for optimization/generation.

Return true to optimize the image, false otherwise.

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        minimizer: {
          filter: (source, sourcePath) => {
            // The `source` argument is a `Buffer` of source file
            // The `sourcePath` argument is an absolute path to source
            if (source.byteLength < 8192) {
              return false;
            }

            return true;
          },
          implementation: ImageMinimizerPlugin.imageminMinify,
          options: {
            plugins: [
              "imagemin-gifsicle",
              "imagemin-mozjpeg",
              "imagemin-pngquant",
              "imagemin-svgo",
            ],
          },
        },
      }),
    ],
  },
};
filename

Type:

type filename =
  | string
  | ((
      pathData: {
        filename?: string | undefined;
      },
      assetInfo?: import("webpack").AssetInfo | undefined,
    ) => string)
  | undefined;

Default: undefined

Allows to set the filename. Supported values see in webpack template strings, File-level section.

We also support [width] and [height] placeholders (only sharp and squoosh).

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        minimizer: {
          filename: "optimized-[name][ext]",
          implementation: ImageMinimizerPlugin.sharpMinify,
          // Options
          options: {
            encodeOptions: {
              jpeg: {
                quality: 90,
              },
            },
          },
        },
      }),
    ],
  },
};

Example function usage:

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        minimizer: {
          filename: () => "optimized-[name][ext]",
          implementation: ImageMinimizerPlugin.sharpMinify,
          // Options
          options: {
            encodeOptions: {
              jpeg: {
                quality: 90,
              },
            },
          },
        },
      }),
    ],
  },
};

generator

Type:

type generator = Array<{
  implementation: (
    original: {
      filename: string;
      data: Buffer;
      warnings: Array<Error>;
      errors: Array<Error>;
      info: import("webpack").AssetInfo;
    },
    options?:
      | {
          [key: string]: any;
        }
      | undefined,
  ) => Promise<{
    filename: string;
    data: Buffer;
    warnings: Array<Error>;
    errors: Array<Error>;
    info: import("webpack").AssetInfo;
  }> & {
    setup?: (() => void) | undefined;
    teardown?: (() => void) | undefined;
  };
  options?:
    | {
        [key: string]: any;
      }
    | undefined;
  filter?: (source: Buffer, sourcePath: string) => boolean | undefined;
  filename?:
    | string
    | ((
        pathData: {
          filename?: string | undefined;
        },
        assetInfo?: import("webpack").AssetInfo | undefined,
      ) => string)
    | undefined;
  preset?: string | undefined;
  type?: "import" | "asset" | undefined;
}>;

Default: undefined

Allow to setup default generators. Useful if you need generate webp/avif/etc from other formats.

Warning

If no generator was found for the image (i.e. no ?as=webp was found in query params), the minimizer option will be used. Therefore, it is recommended to configure generator outputs optimized image.

Warning

The option will not work if you disable loader (i.e. set the loader option to false).

Available generators

  • ImageMinimizerPlugin.imageminGenerate
  • DEPRECATED ImageMinimizerPlugin.squooshGenerate
  • ImageMinimizerPlugin.sharpGenerate

Generator example for imagemin

Example webp generator:

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        generator: [
          {
            // You can apply generator using `?as=webp`, you can use any name and provide more options
            preset: "webp",
            implementation: ImageMinimizerPlugin.imageminGenerate,
            options: {
              // Please specify only one plugin here, multiple plugins will not work
              plugins: ["imagemin-webp"],
            },
          },
        ],
      }),
    ],
  },
};

DEPRECATED Generator example for squoosh

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        generator: [
          {
            // You can apply generator using `?as=webp`, you can use any name and provide more options
            preset: "webp",
            implementation: ImageMinimizerPlugin.squooshGenerate,
            options: {
              encodeOptions: {
                // Please specify only one codec here, multiple codecs will not work
                webp: {
                  quality: 90,
                },
              },
            },
          },
        ],
      }),
    ],
  },
};

Generator example for sharp

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        generator: [
          {
            // You can apply generator using `?as=webp`, you can use any name and provide more options
            preset: "webp",
            implementation: ImageMinimizerPlugin.sharpGenerate,
            options: {
              encodeOptions: {
                // Please specify only one codec here, multiple codecs will not work
                webp: {
                  quality: 90,
                },
              },
            },
          },
        ],
      }),
    ],
  },
};

Now you can generate the new image using:

// Old approach for getting URL
import webp from "./file.jpg?as=webp";

// Assets modules
console.log(new URL("./file.jpg?as=webp"));
div {
  background: url("./file.jpg?as=webp");
}

You can use ?as=webp in any type of files.

Example multiple generators:

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        generator: [
          {
            // You can apply generator using `?as=webp`, you can use any name and provide more options
            preset: "webp",
            implementation: ImageMinimizerPlugin.sharpGenerate,
            options: {
              encodeOptions: {
                webp: {
                  lossless: false,
                },
              },
            },
          },
          {
            // You can apply generator using `?as=avif`, you can use any name and provide more options
            preset: "avif",
            implementation: ImageMinimizerPlugin.sharpGenerate,
            options: {
              encodeOptions: {
                avif: {
                  lossless: false,
                },
              },
            },
          },
        ],
      }),
    ],
  },
};

squoosh and sharp generator supports more options, for example you can resize an image:

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        generator: [
          {
            // You can apply generator using `?as=webp-100-50`, you can use any name and provide more options
            preset: "webp-100-50",
            // implementation: ImageMinimizerPlugin.squooshGenerate,
            implementation: ImageMinimizerPlugin.sharpGenerate,
            options: {
              resize: {
                enabled: true,
                width: 100,
                height: 50,
              },
              encodeOptions: {
                webp: {
                  quality: 90,
                },
              },
            },
          },
        ],
      }),
    ],
  },
};

You can find more information here.

Generator example for user defined implementation

You can use your own generator implementation.

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        generator: [
          {
            // You can apply generator using `?as=webp`, you can use any name and provide more options
            preset: "webp",
            implementation: async (original, options) => {
              const inputExt = path.extname(original.filename).toLowerCase();

              if (inputExt !== ".xxx") {
                // Store error and return `null` if the implementation does not support this file type
                original.errors.push(error);
                return null;
              }

              let result;

              try {
                result = await minifyAndReturnBuffer(original.data);
              } catch (error) {
                // Store error and return `null` if there was an error
                original.errors.push(error);
                return null;
              }

              return {
                filename: original.filename,
                data: result,
                warnings: [...original.warnings],
                errors: [...original.errors],
                info: {
                  ...original.info,
                  // Please always set it to prevent double minification
                  generated: true,
                  // Optional
                  generatedBy: ["custom-name-of-minification"],
                },
              };
            },
            options: {
              // Your options
            },
          },
        ],
      }),
    ],
  },
};

Generator options

type

Type:

type type = "import" | "asset" | undefined;

Default: "import"

Allows you to apply the generator for import or assets from compilation (useful for copied assets). By default, generators are applying on import/require, but sometimes you need to generate new images from other plugins (for example - copy-webpack-plugin), if you need this, please set asset value for the type option.

webpack.config.js

const CopyPlugin = require("copy-webpack-plugin");
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.imageminMinify,
          options: {
            plugins: [
              "imagemin-gifsicle",
              "imagemin-mozjpeg",
              "imagemin-pngquant",
              "imagemin-svgo",
            ],
          },
        },
        generator: [
          {
            // Apply generator for copied assets
            type: "asset",
            // You can use `ImageMinimizerPlugin.squooshGenerate`
            // You can use `ImageMinimizerPlugin.sharpGenerate`
            implementation: ImageMinimizerPlugin.imageminGenerate,
            options: {
              plugins: ["imagemin-webp"],
            },
          },
        ],
      }),
    ],
  },
  plugins: [new CopyPlugin({ patterns: ["images/**/*.png"] })],
};
preset

Type:

type preset = string | undefined;

Default: undefined

Configure the name of preset, i.e. you can use it in ?as=name.

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        generator: [
          {
            preset: "name",
            // Implementation
            implementation: ImageMinimizerPlugin.sharpMinify,
            options: {
              encodeOptions: {
                jpeg: {
                  quality: 85,
                },
              },
            },
          },
        ],
      }),
    ],
  },
};
implementation

Type:

type implementation = (
  original: {
    filename: string;
    data: Buffer;
    warnings: Array<Error>;
    errors: Array<Error>;
    info: import("webpack").AssetInfo;
  },
  options?:
    | {
        [key: string]: any;
      }
    | undefined,
) => Promise<{
  filename: string;
  data: Buffer;
  warnings: Array<Error>;
  errors: Array<Error>;
  info: import("webpack").AssetInfo;
}> & {
  setup?: (() => void) | undefined;
  teardown?: (() => void) | undefined;
};

Default: undefined

Configure the default implementation.

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        generator: [
          {
            preset: "name",
            // Implementation
            implementation: ImageMinimizerPlugin.sharpMinify,
            options: {
              encodeOptions: {
                jpeg: {
                  quality: 85,
                },
              },
            },
          },
        ],
      }),
    ],
  },
};
options

Type:

type options = {
  [key: string]: any;
};

Default: undefined

Options for the implementation option (i.e. options for imagemin/squoosh/sharp/custom implementation).

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        generator: [
          {
            preset: "name",
            implementation: ImageMinimizerPlugin.sharpMinify,
            // Options
            options: {
              encodeOptions: {
                jpeg: {
                  quality: 90,
                },
              },
            },
          },
        ],
      }),
    ],
  },
};
filter

Type:

type filter = (source: Buffer, sourcePath: string) => boolean;

Default: () => true

Allows filtering of images for optimization/generation.

Return true to optimize the image, false otherwise.

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        generator: [
          {
            preset: "name",
            filter: (source, sourcePath) => {
              // The `source` argument is a `Buffer` of source file
              // The `sourcePath` argument is an absolute path to source
              if (source.byteLength < 8192) {
                return false;
              }

              return true;
            },
            implementation: ImageMinimizerPlugin.imageminMinify,
            options: {
              plugins: [
                "imagemin-gifsicle",
                "imagemin-mozjpeg",
                "imagemin-pngquant",
                "imagemin-svgo",
              ],
            },
          },
        ],
      }),
    ],
  },
};
filename

Type:

type filename =
  | string
  | ((
      pathData: PathData,
      assetInfo?: import("webpack").AssetInfo | undefined,
    ) => string);

Default: undefined

Allows to set the filename. Supported values see in webpack template strings, File-level section.

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        generator: [
          {
            preset: "name",
            filename: "generated-[name][ext]",
            implementation: ImageMinimizerPlugin.sharpMinify,
            // Options
            options: {
              encodeOptions: {
                jpeg: {
                  quality: 90,
                },
              },
            },
          },
        ],
      }),
    ],
  },
};

Example of function usage:

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        generator: [
          {
            preset: "name",
            filename: () => "generated-[name][ext]",
            implementation: ImageMinimizerPlugin.sharpMinify,
            // Options
            options: {
              encodeOptions: {
                jpeg: {
                  quality: 90,
                },
              },
            },
          },
        ],
      }),
    ],
  },
};

severityError

Type:

type severityError = string;

Default: 'error'

Allows to choose how errors are displayed.

Сan have the following values:

  • 'off' - suppresses errors and warnings
  • 'warning' - emit warnings instead errors
  • 'error' - emit errors

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        severityError: "warning",
        minimizer: {
          implementation: ImageMinimizerPlugin.imageminMinify,
          options: {
            plugins: [
              "imagemin-gifsicle",
              "imagemin-mozjpeg",
              "imagemin-pngquant",
              "imagemin-svgo",
            ],
          },
        },
      }),
    ],
  },
};

loader

Type:

type loader = boolean;

Default: true

Automatically adding built-in loader, used to optimize/generate images.

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        loader: false,
        // `generator` will not work in this case
        minimizer: {
          implementation: ImageMinimizerPlugin.imageminMinify,
          options: {
            plugins: [
              "imagemin-gifsicle",
              "imagemin-mozjpeg",
              "imagemin-pngquant",
              "imagemin-svgo",
            ],
          },
        },
      }),
    ],
  },
};

concurrency

Type:

type concurrency = number;

Default: Math.max(1, os.cpus().length - 1)

Maximum number of concurrency optimization processes in one time.

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        concurrency: 3,
        minimizer: {
          implementation: ImageMinimizerPlugin.imageminMinify,
          options: {
            plugins: [
              "imagemin-gifsicle",
              "imagemin-mozjpeg",
              "imagemin-pngquant",
              "imagemin-svgo",
            ],
          },
        },
      }),
    ],
  },
};

deleteOriginalAssets

Type:

type deleteOriginalAssets = boolean;

Default: true

Allows removing original assets after optimization.

Please use this option if you are set the filename option for the minimizer option, disable loader: false and want to keep optimized and not optimized assets.

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        // Disable loader
        loader: false,
        // Allows to keep original asset and minimized assets with different filenames
        deleteOriginalAssets: false,
        minimizer: {
          filename: "[path][name].webp",
          implementation: ImageMinimizerPlugin.imageminMinify,
          options: {
            plugins: [
              "imagemin-gifsicle",
              "imagemin-mozjpeg",
              "imagemin-pngquant",
              "imagemin-svgo",
            ],
          },
        },
      }),
    ],
  },
};

Loader Options

minimizer

Type:

type minimizer =
  | {
      implementation: (
        original: {
          filename: string;
          data: Buffer;
          warnings: Array<Error>;
          errors: Array<Error>;
          info: import("webpack").AssetInfo;
        },
        options?:
          | {
              [key: string]: any;
            }
          | undefined,
      ) => Promise<{
        filename: string;
        data: Buffer;
        warnings: Array<Error>;
        errors: Array<Error>;
        info: import("webpack").AssetInfo;
      }> & {
        setup?: (() => void) | undefined;
        teardown?: (() => void) | undefined;
      };
      options?:
        | {
            [key: string]: any;
          }
        | undefined;
      filter?: (source: Buffer, sourcePath: string) => boolean | undefined;
      filename?:
        | string
        | ((
            pathData: {
              filename?: string | undefined;
            },
            assetInfo?: import("webpack").AssetInfo | undefined,
          ) => string)
        | undefined;
    }
  | Array<{
      implementation: (
        original: {
          filename: string;
          data: Buffer;
          warnings: Array<Error>;
          errors: Array<Error>;
          info: import("webpack").AssetInfo;
        },
        options?:
          | {
              [key: string]: any;
            }
          | undefined,
      ) => Promise<{
        filename: string;
        data: Buffer;
        warnings: Array<Error>;
        errors: Array<Error>;
        info: import("webpack").AssetInfo;
      }> & {
        setup?: (() => void) | undefined;
        teardown?: (() => void) | undefined;
      };
      options?:
        | {
            [key: string]: any;
          }
        | undefined;
      filter?: (source: Buffer, sourcePath: string) => boolean | undefined;
      filename?:
        | string
        | ((
            pathData: {
              filename?: string | undefined;
            },
            assetInfo?: import("webpack").AssetInfo | undefined,
          ) => string)
        | undefined;
    }>;

Default: undefined

Allows to setup default minimizer.

Loader minimizer example for imagemin

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  module: {
    rules: [
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        type: "asset",
      },
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        loader: ImageMinimizerPlugin.loader,
        enforce: "pre",
        options: {
          minimizer: {
            implementation: ImageMinimizerPlugin.imageminMinify,
            options: {
              plugins: [
                "imagemin-gifsicle",
                "imagemin-mozjpeg",
                "imagemin-pngquant",
                "imagemin-svgo",
              ],
            },
          },
        },
      },
    ],
  },
};

For more information and supported options please read here.

generator

Type:

type generator = Array<{
  implementation: TransformerFunction<T>;
  options?: BasicTransformerOptions<T>;
  filter?: FilterFn | undefined;
  filename?: string | FilenameFn | undefined;
  preset?: string | undefined;
  type?: "import" | "asset" | undefined;
}>;

Default: undefined

Allow to setup default generators. Useful if you need generate webp/avif/etc from other formats.

Loader generator example for imagemin

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  module: {
    rules: [
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        type: "asset",
      },
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        loader: ImageMinimizerPlugin.loader,
        enforce: "pre",
        options: {
          generator: [
            {
              preset: "webp",
              implementation: ImageMinimizerPlugin.imageminGenerate,
              options: {
                plugins: ["imagemin-webp"],
              },
            },
          ],
        },
      },
    ],
  },
};

For more information and supported options please read here.

severityError

Type:

type severityError = string;

Default: 'error'

Allows to choose how errors are displayed.

Сan have the following values:

  • 'off' - suppresses errors and warnings
  • 'warning' - emit warnings instead errors
  • 'error' - emit errors

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  module: {
    rules: [
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        type: "asset",
      },
      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        use: [
          {
            loader: ImageMinimizerPlugin.loader,
            options: {
              severityError: "warning",
              minimizerOptions: {
                plugins: ["gifsicle"],
              },
            },
          },
        ],
      },
    ],
  },
};

Additional API

imageminNormalizeConfig(config)

The function normalizes configuration (converts plugins names and options to Functions) for using in imagemin package directly.

const imagemin = require("imagemin");
const { imageminNormalizeConfig } = require("image-minimizer-webpack-plugin");

/*
  console.log(imageminConfig);
  =>
  {
    plugins: [Function, Function],
    pluginsMeta: [
      { name: "imagemin-jpegtran", version: "x.x.x", options: {} },
      { name: "imagemin-pngquant", version: "x.x.x", options: { quality: [0.6, 0.8] }
    ]
  }
*/

(async () => {
  const imageminConfig = await imageminNormalizeConfig({
    plugins: ["jpegtran", ["pngquant", { quality: [0.6, 0.8] }]],
  });
  const files = await imagemin(["images/*.{jpg,png}"], {
    destination: "build/images",
    plugins: imageminConfig.plugins,
  });

  console.log(files);
  // => [{data: <Buffer 89 50 4e …>, path: 'build/images/foo.jpg'}, …]
})();

Examples

Optimize images based on size

You can use difference options (like progressive/interlaced/etc.) based on image size (example - don't do progressive transformation for small images).

What is progressive image? Answer here.

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.imageminMinify,
          options: {
            plugins: [["jpegtran", { progressive: true }]],
          },
          // Only apply this one to files equal to or over 8192 bytes
          filter: (source) => {
            if (source.byteLength >= 8192) {
              return true;
            }

            return false;
          },
        },
      }),
      new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.imageminMinify,
          options: {
            plugins: [["jpegtran", { progressive: false }]],
          },
          // Only apply this one to files under 8192
          filter: (source) => {
            if (source.byteLength < 8192) {
              return true;
            }

            return false;
          },
        },
      }),
    ],
  },
};

Optimize and generate webp images

  • imagemin

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.imageminMinify,
          options: {
            plugins: [
              "imagemin-gifsicle",
              "imagemin-mozjpeg",
              "imagemin-pngquant",
              "imagemin-svgo",
            ],
          },
        },
        generator: [
          {
            // You can apply generator using `?as=webp`, you can use any name and provide more options
            preset: "webp",
            implementation: ImageMinimizerPlugin.imageminGenerate,
            options: {
              plugins: ["imagemin-webp"],
            },
          },
        ],
      }),
    ],
  },
};
  • DEPRECATED squoosh

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.squooshMinify,
        },
        generator: [
          {
            // You can apply generator using `?as=webp`, you can use any name and provide more options
            preset: "webp",
            implementation: ImageMinimizerPlugin.squooshGenerate,
            options: {
              encodeOptions: {
                webp: {
                  quality: 90,
                },
              },
            },
          },
        ],
      }),
    ],
  },
};
  • sharp

webpack.config.js

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.sharpMinify,
        },
        generator: [
          {
            // You can apply generator using `?as=webp`, you can use any name and provide more options
            preset: "webp",
            implementation: ImageMinimizerPlugin.sharpGenerate,
            options: {
              encodeOptions: {
                webp: {
                  quality: 90,
                },
              },
            },
          },
        ],
      }),
    ],
  },
};

Generate webp images from copied assets

  • imagemin

webpack.config.js

const CopyPlugin = require("copy-webpack-plugin");
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.imageminMinify,
          options: {
            plugins: [
              "imagemin-gifsicle",
              "imagemin-mozjpeg",
              "imagemin-pngquant",
              "imagemin-svgo",
            ],
          },
        },
        generator: [
          {
            type: "asset",
            implementation: ImageMinimizerPlugin.imageminGenerate,
            options: {
              plugins: ["imagemin-webp"],
            },
          },
        ],
      }),
    ],
  },
  plugins: [new CopyPlugin({ patterns: ["images/**/*.png"] })],
};
  • DEPRECATED squoosh

webpack.config.js

const CopyPlugin = require("copy-webpack-plugin");
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.squooshMinify,
        },
        generator: [
          {
            type: "asset",
            implementation: ImageMinimizerPlugin.squooshGenerate,
            options: {
              encodeOptions: {
                webp: {
                  quality: 90,
                },
              },
            },
          },
        ],
      }),
    ],
  },
  plugins: [new CopyPlugin({ patterns: ["images/**/*.png"] })],
};
  • sharp

webpack.config.js

const CopyPlugin = require("copy-webpack-plugin");
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.sharpMinify,
        },
        generator: [
          {
            type: "asset",
            implementation: ImageMinimizerPlugin.sharpGenerate,
            options: {
              encodeOptions: {
                webp: {
                  quality: 90,
                },
              },
            },
          },
        ],
      }),
    ],
  },
  plugins: [new CopyPlugin({ patterns: ["images/**/*.png"] })],
};

Contributing

Please take a moment to read our contributing guidelines if you haven't yet done so.

CONTRIBUTING

License

MIT

image-minimizer-webpack-plugin's People

Contributors

alexander-akait avatar amareshsm avatar anshumanv avatar biswasoren avatar cap-bernardito avatar chenxsan avatar dependabot[bot] avatar ejulen avatar ersachin3112 avatar evilebottnawi avatar francescolaffi avatar glen-84 avatar greenkeeper[bot] avatar lfkwtz avatar mdarveau avatar mickyfen17 avatar mischah avatar pierw avatar rax7 avatar snitin315 avatar webdeveric avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

image-minimizer-webpack-plugin's Issues

Bog In Plugin image-minimizer-webpack-plugin

Hi, when I create an instance of the module when of image-minimizer-webpack-plugin new instance created, it gives me an error and says that there is no property called minify, please correct this bug

bug
result

Webpack 4 compatibility - Error 'tapProcess' undefined

  • Operating System: masOS
  • Node Version: v12.14.1
  • NPM Version: 6.13.4
  • webpack Version: [email protected]
  • image-minimizer-webpack-plugin Version: 2.0.0

Expected Behavior

Actual Behavior

Screen Shot 2020-12-22 at 18 23 35

Code

const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
 plugins: [
    new ImageMinimizerPlugin({
      minimizerOptions: {
        // Lossless optimization with custom option
        // Feel free to experiment with options for better result for you
        plugins: [
          ['gifsicle', { interlaced: true }],
          ['jpegtran', { progressive: true }],
          ['optipng', { optimizationLevel: 5 }],
          [
            'svgo',
            {
              plugins: [
                {
                  removeViewBox: false,
                },
              ],
            },
          ],
        ],
      },
    }),
  ]
// additional code, HEY YO remove this block if you don't need it

How Do We Reproduce?

`module.rule.generator.emit = false` results in different emitted filenames

  • Operating System: macOS
  • Node Version: 14.17.0
  • NPM Version: 7.18.1
  • webpack Version: 5.40.0
  • image-minimizer-webpack-plugin Version: 2.2.0

Expected Behavior

When module.rule.generator.emit is set to false for asset resources, webpack is supposed to emit the same filename as when it's set to true.

Actual Behavior

This doesn't work correctly if there's an image minimizer in the chain, presumably because the minifier is only running when {emit: true} and ends up influencing the asset hash.

Note that this reproduces regardless of the asset filename, e.g., setting it to something like [contenthash][ext] does not fix the issue.

Not sure if this bug is specific to image-minimizer-webpack-plugin or generally an issue with webpack, so I'm reporting it in both places. (See webpack/webpack#13628.)

Code

Here is a minimal reproduction repo.

How Do We Reproduce?

See the readme and test file in the repo for details.

npm install failed

  • Operating System: windows 10
  • Node Version: v14.15.1
  • NPM Version:v6.14.8
  • webpack Version:v5.12.3
  • image-minimizer-webpack-plugin Version:v2.2.0

Expected Behavior

i use npm install to download these packages,but i fail.Then i use yarn,i fail again.

Actual Behavior

download fail
error

  [email protected] postinstall F:\workspace_github\homeSite\node_modules\gifsicle
> node lib/install.js

  ‼ read ECONNRESET
  ‼ gifsicle pre-build test failed
  i compiling from source
  × Error: Command failed: C:\Windows\system32\cmd.exe /s /c "autoreconf -ivf"
'autoreconf' �����ڲ����ⲿ���Ҳ���ǿ����еij���
���������ļ���


    at F:\workspace_github\homeSite\node_modules\bin-build\node_modules\execa\index.js:231:11
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at async Promise.all (index 0)

Code

npm install imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo --save-dev
yarn add imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo -D

How Do We Reproduce?

you can see my code in here.
option file is in config,webpack.common.js.
you can use these commands to repeat my problem.

git clone https://github.com/clark-cui/homeSite
npm i
npm install imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo --save-dev

squooshGenerate error: " TypeError: Cannot read properties of undefined (reading 'get')"

with squooshMinify

module: {
  rules: [
    {
      test: /\.(gif|png|jpe?g|svg|ico)$/,
...
optimization: {
  minimize,
  minimizer: [
    new ImageMinimizerPlugin({
      minimizer: {
        implementation: ImageMinimizerPlugin.squooshMinify,
        options: {
          encodeOptions: {
            oxipng: {
              level: 6,
            },
          },
        },
      },

png minification works.

switch, instead, to squooshGenerate, for png->webp generation,

module: {
  rules: [
    {
      test: /\.(gif|png|jpe?g|svg|ico)$/,
...
  optimization: {
    minimize,
    minimizer: [
      new ImageMinimizerPlugin({
        generator: [
          {
            implementation: ImageMinimizerPlugin.squooshGenerate,
            options: {
              encodeOptions: {
                webp: {
                  quality: 90,
                },
              },
            },
          },
        ],

on build, fails

webpack --mode=production  --progress --profile
  [webpack-cli] HookWebpackError: Cannot read properties of undefined (reading 'get')
      at makeWebpackError (/work/test01/.yarn/__virtual__/webpack-virtual-7a36ac1fb4/0/cache/webpack-npm-5.68.0-f34609ad11-ac6efd861a.zip/node_modules/webpack/lib/HookWebpackError.js:48:9)
      at /work/test01/.yarn/__virtual__/webpack-virtual-7a36ac1fb4/0/cache/webpack-npm-5.68.0-f34609ad11-ac6efd861a.zip/node_modules/webpack/lib/Compilation.js:3057:12
      at eval (eval at create (/work/test01/.yarn/cache/tapable-npm-2.2.1-8cf5ff3039-3b7a1b4d86.zip/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:17:1)
      at fn (/work/test01/.yarn/__virtual__/webpack-virtual-7a36ac1fb4/0/cache/webpack-npm-5.68.0-f34609ad11-ac6efd861a.zip/node_modules/webpack/lib/Compilation.js:478:17)
      at _next7 (eval at create (/work/test01/.yarn/cache/tapable-npm-2.2.1-8cf5ff3039-3b7a1b4d86.zip/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:14:1)
      at eval (eval at create (/work/test01/.yarn/cache/tapable-npm-2.2.1-8cf5ff3039-3b7a1b4d86.zip/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:34:1)
      at runMicrotasks (<anonymous>)
      at processTicksAndRejections (node:internal/process/task_queues:96:5)
  -- inner error --
  TypeError: Cannot read properties of undefined (reading 'get')
      at WebpackAssetsManifest.handleProcessAssetsAnalyse (/work/test01/.yarn/__virtual__/webpack-assets-manifest-virtual-f2c3bb0a34/0/cache/webpack-assets-manifest-npm-5.1.0-fad26f5290-30b0929f6a.zip/node_modules/webpack-assets-manifest/src/WebpackAssetsManifest.js:467:37)
      at fn (/work/test01/.yarn/__virtual__/webpack-virtual-7a36ac1fb4/0/cache/webpack-npm-5.68.0-f34609ad11-ac6efd861a.zip/node_modules/webpack/lib/Compilation.js:476:10)
      at _next7 (eval at create (/work/test01/.yarn/cache/tapable-npm-2.2.1-8cf5ff3039-3b7a1b4d86.zip/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:14:1)
      at eval (eval at create (/work/test01/.yarn/cache/tapable-npm-2.2.1-8cf5ff3039-3b7a1b4d86.zip/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:34:1)
      at runMicrotasks (<anonymous>)
      at processTicksAndRejections (node:internal/process/task_queues:96:5)
  caused by plugins in Compilation.hooks.processAssets
  TypeError: Cannot read properties of undefined (reading 'get')
      at WebpackAssetsManifest.handleProcessAssetsAnalyse (/work/test01/.yarn/__virtual__/webpack-assets-manifest-virtual-f2c3bb0a34/0/cache/webpack-assets-manifest-npm-5.1.0-fad26f5290-30b0929f6a.zip/node_modules/webpack-assets-manifest/src/WebpackAssetsManifest.js:467:37)
      at fn (/work/test01/.yarn/__virtual__/webpack-virtual-7a36ac1fb4/0/cache/webpack-npm-5.68.0-f34609ad11-ac6efd861a.zip/node_modules/webpack/lib/Compilation.js:476:10)
      at _next7 (eval at create (/work/test01/.yarn/cache/tapable-npm-2.2.1-8cf5ff3039-3b7a1b4d86.zip/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:14:1)
      at eval (eval at create (/work/test01/.yarn/cache/tapable-npm-2.2.1-8cf5ff3039-3b7a1b4d86.zip/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:34:1)
      at runMicrotasks (<anonymous>)
      at processTicksAndRejections (node:internal/process/task_queues:96:5)
npx webpack-cli info

  System:
    OS: Linux 5.16 Fedora Linux 35 (Thirty Five)
    CPU: (16) x64 AMD Ryzen 7 3700X 8-Core Processor
    Memory: 52.91 GB / 62.70 GB
  Binaries:
    Node: 17.4.0 - /usr/local/bin/node
    Yarn: 3.2.0-rc.13 - /usr/local/bin/yarn
    npm: 8.3.1 - /usr/local/bin/npm
  Browsers:
    Brave Browser: 98.1.35.100
    Chrome: 98.0.4758.80
    Firefox: 96.0.3

Not working gif optimizer?

Iam use such configuration:

const merge = require('webpack-merge')
const dev = require('./webpack.dev.config.js')
const ImageminPlugin = require('imagemin-webpack')

module.exports = merge(dev, {
  devtool: 'none',
  plugins: [
    new ImageminPlugin({
      name: '[path][name].[ext]',
      imageminOptions: {
        plugins: [
          ['gifsicle', { interlaced: true, optimizationLevel: 3 }],
          ['mozjpeg', { quality: 73, progressive: true }],
          ['pngquant', { quality: [0.6, 0.8] }]
        ]
      }
    })
  ]
})

package.json:

{
    "imagemin-gifsicle": "^7.0.0",
    "imagemin-mozjpeg": "^9.0.0",
    "imagemin-pngquant": "^9.0.0",
    "imagemin-webpack": "^5.1.1"
}
  • 1.jpg(7,1MB) => 1.jpg(1,62MB)
  • 1.png(7,16MB) => 1.png(2,06MB)
  • 1.gif(10,33MB) => 1.gif(10,33MB)

gif image not is optimized, why?

Add typescript type definitions

Are there any plans to add typescript type definitions ?

Feature Proposal

Add support for typescript type definitions.

Feature Use Case

Having a webpack.config.ts file will result in errors for not providing a type definition for this.

Cannot read property 'tapPromise' of undefined

  • Operating System: Debian Buster
  • Node Version: v14.13.0
  • NPM Version: 6.14.8
  • webpack Version: 4.43.0
  • image-minimizer-webpack-plugin Version: 2.1.0

Expected Behavior

I expected to optimize my assets images when running npm run build.

Actual Behavior

Running npm run build produce the error:

> react-app-rewired build

Creating an optimized production build...
Failed to compile.

Cannot read property 'tapPromise' of undefined

Code

// webpack.config.js
// If your code blocks are over 20 lines, please paste a link to a gist
// (https://gist.github.com).
// additional code, HEY YO remove this block if you don't need it

How Do We Reproduce?

Using create-react-app and react-app-rewired, this is what I did:

npm i --save-dev image-minimizer-webpack-plugin  imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo

In config-override.js:

const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');

module.exports = {
  webpack: (config, env) => {
    config.plugins = (config.plugins || []).concat([
      new ImageMinimizerPlugin({
        minimizerOptions: {
          // Lossless optimization with custom option
          // Feel free to experiment with options for better result for you
          plugins: [
            ['gifsicle', { interlaced: true }],
            ['jpegtran', { progressive: true }],
            ['optipng', { optimizationLevel: 5 }],
            [
              'svgo',
              {
                plugins: [
                  {
                    removeViewBox: false,
                  },
                ],
              },
            ],
          ],
        },
      }),
    ]);
  },
};

Compilation errors when used with zsh shell on mac os (and possibly Ubuntu)

We have a build system that required us to switch to zsh shell on our mac. We started seeing this error when making builds:

​ModuleError: Module Error (from ../node_modules/imagemin-webpack/src/imagemin-loader.js):
   ​spawn /Users/jenkins/workspace/workspace/Safer_staging/node_modules/optipng-bin/vendor/optipng ENOENT
       ​at Object.emitError (/Users/jenkins/workspace/workspace/Safer_staging/node_modules/webpack/lib/NormalModule.js:172:6)
       ​at /Users/jenkins/workspace/workspace/Safer_staging/node_modules/imagemin-webpack/src/imagemin-loader.js:44:16
       ​at Array.forEach (<anonymous>)
       ​at /Users/jenkins/workspace/workspace/Safer_staging/node_modules/imagemin-webpack/src/imagemin-loader.js:43:23

We had to downgrade imagemin-optipng from 7.1.0 to 6.0.0 to get the builds to work.

Webpack 5 Compatibility

  • Operating System: MacOS Catalina
  • Node Version: v12.16.3
  • NPM Version: 6.14.4
  • webpack Version: 5.1.2
  • image-minimizer-webpack-plugin Version: 1.0.0

Feature Proposal

Compatibility with Webpack 5. I don't see a pr or new branch regarding this, was wondering if this was part of the roadmap and if there was an ETA?

95% emitting emit ImageMinimizerPlugin(node:79918) [DEP_WEBPACK_COMPILATION_ASSETS] DeprecationWarning: Compilation.assets will be frozen in future, all modifications are deprecated.
BREAKING CHANGE: No more changes should happen to Compilation.assets after sealing the Compilation.
	Do changes to assets earlier, e. g. in Compilation.hooks.processAssets.
	Make sure to select an appropriate stage from Compilation.PROCESS_ASSETS_STAGE_*.

Unexpected behavior with favicons-webpack-plugin

While using the favicons-webpack-plugin along side the imagemin-webpack package, I am facing unexpected behavior regarding duplicate images being generated.

The imagemin-webpack plugin is generating duplicates of the images generated by the favicons-webpack-plugin with hashed filenames, and in a directory different than the one specified by the favicons-webpack-plugin

As a beginner, I am confused as to what the reason for the duplicate images is. It would be a huge help for me if you could please advise what the cause of this could be and how I could solve this. Please note the directory tree diagrams included below which show the duplicate images (with hashed filenames) being generated with the imagemin-webpack plugin enabled.

Thanking you,

Source

package.json
{
  "name": "favicon-imagemin",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "webpack --mode production"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "favicons-webpack-plugin": "^1.0.2",
    "file-loader": "^4.2.0",
    "html-webpack-plugin": "^3.2.0",
    "imagemin-optipng": "^7.0.0",
    "imagemin-webpack": "^5.1.0",
    "webpack": "^4.40.2",
    "webpack-cli": "^3.3.9"
  }
}

webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ImageMinWebpack = require('imagemin-webpack');
const FavIconsWebpackPlugin = require('favicons-webpack-plugin');

module.exports = {
    mode: "production",
    entry: "./src/index.js",
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: "js/[hash].js"
    },
    module: {
        rules: [
            {
                test: /\.png$/,
                use: {
                    loader: "file-loader",
                    options: {
                        name: '[name].[ext]',
                        outputPath: 'assets/'
                        // interpolate:true,
                    }
                }
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: "./src/template.html"
        }),

        new ImageMinWebpack(
            {
                bail: false,
                cache: true,
                imageminOptions: {
                    plugins: [
                        // ["mozjpeg", {quality: 50}],
                        ["optipng", {optimizationLevel: 5}],
                    ]
                }
            }
        ),
        new FavIconsWebpackPlugin({
            logo: './src/assets/favicon/logo.png',
            mode: 'webapp', // optional can be 'webapp' or 'light' - 'webapp' by default
            devMode: 'webapp', // optional can be 'webapp' or 'light' - 'light' by default
            cache: true,
            outputPath: 'assets/favicon', //this works
            prefix: 'assets/favicon',
            inject: true,
            favicons: {
                appName: 'my-app',
                appDescription: 'My awesome App',
                developerName: 'Me',
                developerURL: null, // prevent retrieving from the nearest package.json
                background: '#ddd',
                theme_color: '#333',
                icons: {
                    coast: false,
                    yandex: false
                }
            }
        }),
    ]
};

Directory structure

Project directory tree actual results
Results with imagemin-webpack plugin enabled
|-- dist
|   |-- assets
|   |   `-- favicon

# Images generated by the favicons-webpack-plugin

|   |       |-- android-chrome-144x144.png
|   |       |-- android-chrome-192x192.png
|   |       |-- android-chrome-256x256.png
|   |       |-- android-chrome-36x36.png
|   |       |-- android-chrome-384x384.png
|   |       |-- android-chrome-48x48.png
|   |       |-- android-chrome-512x512.png
|   |       |-- android-chrome-72x72.png
|   |       |-- android-chrome-96x96.png
|   |       |-- apple-touch-icon-1024x1024.png
|   |       |-- apple-touch-icon-114x114.png
|   |       |-- apple-touch-icon-120x120.png
|   |       |-- apple-touch-icon-144x144.png
|   |       |-- apple-touch-icon-152x152.png
|   |       |-- apple-touch-icon-167x167.png
|   |       |-- apple-touch-icon-180x180.png
|   |       |-- apple-touch-icon-57x57.png
|   |       |-- apple-touch-icon-60x60.png
|   |       |-- apple-touch-icon-72x72.png
|   |       |-- apple-touch-icon-76x76.png
|   |       |-- apple-touch-icon-precomposed.png
|   |       |-- apple-touch-icon.png
|   |       |-- apple-touch-startup-image-1182x2208.png
|   |       |-- apple-touch-startup-image-1242x2148.png
|   |       |-- apple-touch-startup-image-1496x2048.png
|   |       |-- apple-touch-startup-image-1536x2008.png
|   |       |-- apple-touch-startup-image-320x460.png
|   |       |-- apple-touch-startup-image-640x1096.png
|   |       |-- apple-touch-startup-image-640x920.png
|   |       |-- apple-touch-startup-image-748x1024.png
|   |       |-- apple-touch-startup-image-750x1294.png
|   |       |-- apple-touch-startup-image-768x1004.png
|   |       |-- browserconfig.xml
|   |       |-- favicon-16x16.png
|   |       |-- favicon-32x32.png
|   |       |-- favicon.ico
|   |       |-- firefox_app_128x128.png
|   |       |-- firefox_app_512x512.png
|   |       |-- firefox_app_60x60.png
|   |       |-- manifest.json
|   |       |-- manifest.webapp
|   |       |-- mstile-144x144.png
|   |       |-- mstile-150x150.png
|   |       |-- mstile-310x150.png
|   |       |-- mstile-310x310.png
|   |       `-- mstile-70x70.png

#unexpected output begins here
#please note these are duplicates of the assets generated by the
#favicons-webpack-plugin with their filenames hashed.
#The duplicates are being output directly into the `dist` folder, while the
# favicon-webpack-plugin is outputting the images to the `dist/assets/favicon`  folder.

|   |-- 08646b39ec47e15288961b85f08ad554.png 
|   |-- 09b1e6ea39422fd719354ff14450706c.png
|   |-- 0c8b9bae48c8fa91b3e339f4eeadd26b.png
|   |-- 1347ebb8841f38ed27ec841d34e7033c.png
|   |-- 176b9bde9d5859502ada8278215582ce.png
|   |-- 188a831fde6a4989120d047ccf9912b0.png
|   |-- 1b2261eef86075aef61842247e6eb6b0.png
|   |-- 1ca2bf4ad84c4b780d5cfd8fff2329a9.png
|   |-- 1d2e1ed62dcd66dcf78368d53a439a6e.png
|   |-- 2357f4423fb19c0d6bd89cf6daa5bb04.png
|   |-- 24811355315564b22372c4da56a6e055.png
|   |-- 2528fc2ba2e1d7f359914fd4cec06beb.png
|   |-- 3c231354c5a857468aa47b173241fb9f.png
|   |-- 452de72f8dfbe9f1b2ec16e6a9c74984.png
|   |-- 4e3823bf457300a66d0815be4ababac3.png
|   |-- 5c18a23fef960589295eea226387dc7a.png
|   |-- 63c53cb12e52c4dcb230c72ea3f454eb.png
|   |-- 6fb20a88272d208c59a864c916335364.png
|   |-- 70ee38ae6fa2a5765f4653d9a8d1b6f0.png
|   |-- 776b4c7ce7c98029225db4812f1e08a8.png
|   |-- 7fbeb6bbcba4d39abfad839bb049d26c.png
|   |-- 84d5e9daac7ac8f7bd03fa1ba72add3c.png
|   |-- 982f8e7c790a299cc28d482cb3e92918.png
|   |-- 9b7707668af4756101dfa2d9c9667278.png
|   |-- b50736d562d335f6ab1cd226306e7599.png
|   |-- bce06d0040fd8eb9e95486967df523e3.png
|   |-- bdfa489637ef025697db260c3907acc3.png
|   |-- c1a82e5927dd96dfa52b758a28916cd3.png
|   |-- ca128c6eb4bb75789b03cb171ecd8b3e.png
|   |-- cc392e8654858afbd326ea2817f50006.png
|   |-- cc6e093acfe21456cb49c024f63a1379.png
|   |-- d11851d31ec05e163390eb0b690463c8.png
|   |-- dd11d211ec1501e3e6199b20dc107ac3.png
|   |-- dedce9461453b4e2e2365f472cc1669e.png
|   |-- e1489216303d6c4b15f03774cb8e64da.png
|   |-- e317c154c05249291ccf5ead6d154522.png
|   |-- e475438bb1781287d0c63cc5120f1a32.png
|   |-- e930fdadba1dc4f0a0e7468f2d32fa2a.png
|   |-- fa5fdf658c7747d32b9817ae45e915b3.png

# end of unexpected output

|   |-- index.html
|   `-- js
|       `-- 1defff432f80b1e6a101.js
|-- package-lock.json
|-- package.json
|-- src
|   |-- assets
|   |   `-- favicon
|   |       `-- logo.png
|   |-- index.js
|   `-- template.html
`-- webpack.config.js

Project directory tree expected results
Results with imagemin-webpack plugin disabled
|-- dist
|   |-- assets
|   |   `-- favicon
|   |       |-- android-chrome-144x144.png
|   |       |-- android-chrome-192x192.png
|   |       |-- android-chrome-256x256.png
|   |       |-- android-chrome-36x36.png
|   |       |-- android-chrome-384x384.png
|   |       |-- android-chrome-48x48.png
|   |       |-- android-chrome-512x512.png
|   |       |-- android-chrome-72x72.png
|   |       |-- android-chrome-96x96.png
|   |       |-- apple-touch-icon-1024x1024.png
|   |       |-- apple-touch-icon-114x114.png
|   |       |-- apple-touch-icon-120x120.png
|   |       |-- apple-touch-icon-144x144.png
|   |       |-- apple-touch-icon-152x152.png
|   |       |-- apple-touch-icon-167x167.png
|   |       |-- apple-touch-icon-180x180.png
|   |       |-- apple-touch-icon-57x57.png
|   |       |-- apple-touch-icon-60x60.png
|   |       |-- apple-touch-icon-72x72.png
|   |       |-- apple-touch-icon-76x76.png
|   |       |-- apple-touch-icon-precomposed.png
|   |       |-- apple-touch-icon.png
|   |       |-- apple-touch-startup-image-1182x2208.png
|   |       |-- apple-touch-startup-image-1242x2148.png
|   |       |-- apple-touch-startup-image-1496x2048.png
|   |       |-- apple-touch-startup-image-1536x2008.png
|   |       |-- apple-touch-startup-image-320x460.png
|   |       |-- apple-touch-startup-image-640x1096.png
|   |       |-- apple-touch-startup-image-640x920.png
|   |       |-- apple-touch-startup-image-748x1024.png
|   |       |-- apple-touch-startup-image-750x1294.png
|   |       |-- apple-touch-startup-image-768x1004.png
|   |       |-- browserconfig.xml
|   |       |-- favicon-16x16.png
|   |       |-- favicon-32x32.png
|   |       |-- favicon.ico
|   |       |-- firefox_app_128x128.png
|   |       |-- firefox_app_512x512.png
|   |       |-- firefox_app_60x60.png
|   |       |-- manifest.json
|   |       |-- manifest.webapp
|   |       |-- mstile-144x144.png
|   |       |-- mstile-150x150.png
|   |       |-- mstile-310x150.png
|   |       |-- mstile-310x310.png
|   |       `-- mstile-70x70.png
|   |-- index.html
|   `-- js
|       `-- 1defff432f80b1e6a101.js
|-- package-lock.json
|-- package.json
|-- src
|   |-- assets
|   |   `-- favicon
|   |       `-- logo.png
|   |-- index.js
|   `-- template.html
`-- webpack.config.js



Update

I discovered the cause of the issue was not having the name property specified in the imagemin-webpack plugin options. By specifying the name property with the value of '[path][name].[ext]' the images are named properly and output to the correct path.

new ImageMinWebpack(
            {
                ...
                name: '[path][name].[ext]',
                ...
            });

I was wondering since when image files that are loaded with file-loader and then when they are compressed with the imagemin plugin, they are output with the correct path and file name by default, without specifying the name property. In contrast, why is specifying the name property required for the images generated by the favicons-webpack-plugin?

Another concern, as I understand, the favicons-webpack-plugin first generates the images to the specified output path and then imagemin-webpack overwrites the files with the respective compressed images. This seems like twice the writes to disk, and just struck out as a concern.

As a beginner I am limited with my understanding of how plugins and loaders work, regarding how they are chained and how the imagemin-webpack plugin 'intercepts' the images (from memory?) in order to be compressed. I apologize for taking your time, if it is not any trouble, I would really appreciate any insight regarding these concerns and if there is something I am not understanding.

Again thanking you, and with much appreciation,

Include filename in squoosh error report

  • Operating System: MacOS
  • Node Version: 16
  • NPM Version: 7
  • webpack Version: 5
  • image-minimizer-webpack-plugin Version: checkout from git, revision 3a38d92

Expected Behavior / Situation

There is an image in my project that is not being accepted by libsquoosh. When running webpack, I'd like image-minimizer-webpack-plugin to tell me what image that is so I can troubleshoot the situation.

Actual Behavior / Situation

The output is less than helpful:

ERROR in Binary blob has an unsupported format

Modification Proposal

Please include the filename in the error output; I modified the error handler in utils/squooshMinify.js:

} catch (error) {
if (imagePool) {
await imagePool.close();
}
result.errors.push(error);
return result;
}

to prepend the error message with the filename:

  } catch (error) {
    if (imagePool) {
      await imagePool.close();
    }

    result.errors.push(`${filename}: ${error}`);
    return result;
  }

This makes the output much more useful:

ERROR in img/favicon.png: Binary blob has an unsupported format

While I don't yet know why libsquoosh is unhappy about the file, at least I can now exclude it from being processed.

Update package in npm registry accordingly

Bug report

Actual Behavior

Hello!
While updating my node modules I came across the issue that the version of the plugin on github
https://github.com/webpack-contrib/image-minimizer-webpack-plugin
coincide with the one published on npm
https://www.npmjs.com/package/image-minimizer-webpack-plugin
(v2.2.0)
Nonetheless the packages differ - the last changes on npm have been made a year ago, which can be spotted by comparing two package.json files - on github you include "webpack": "^5.51.1" as a dependency while on npm it's "^5.12.2".
Could you update you plugin on npm registry accordingly to mirror the last changes?

Expected Behavior

Packages are equal

Union with `image-webpack-loader`

I think will be great to unioin with https://github.com/tcoopman/image-webpack-loader, we already supports these feature and more, so I think we should finish the next major release with more features + squoosh support ⭐ and try to union

/cc @tcoopman What do you think? I can provide more information

[Bug] `data:` protocol trigger error

Bug report

#270 add data: protocol support.

It' will trigger errors in some cases.

Actual Behavior

import data:text/* trigger error because, the implementation only accept image format

It also breaks html-webpack-plugin@5, see that in reproduce sandbox.

https://github.com/jantimon/html-webpack-plugin/blob/0a6568d587a82d88fd3a0617234ca98d26a1e0a6/lib/child-compiler.js#L119

Expected Behavior

Only data:image/* included.

How Do We Reproduce?

https://codesandbox.io/s/image-minimizer-webpack-plugin-error-3qmbi?file=/webpack.config.js

Please paste the results of npx webpack-cli info here, and mention other relevant information

From my case:

ERROR in data:text/abc,1231
Module Error (from ./node_modules/image-minimizer-webpack-plugin/dist/loader.js):
not image
Error: not image
    at Object.implementation (/sandbox/webpack.config.js:15:21)
    at worker (/sandbox/node_modules/image-minimizer-webpack-plugin/dist/worker.js:83:47)
    at Object.loader (/sandbox/node_modules/image-minimizer-webpack-plugin/dist/loader.js:101:24)
 @ ./src/index.js 1:0-28

Solution

For user

Using options.minimizer.filter or options.loader = false can aviod this error.

For Owner

Use data:image/* instead data:*

I can send a PR.

But why allow data:* in the first place?

Allow filename option to be a function

  • Operating System: Ubuntu
  • Node Version: 10.23.1
  • NPM Version: yarn 1.22.5
  • webpack Version: 5.17.0
  • image-minimizer-webpack-plugin Version:2.2.0

Feature Proposal

Allow the filename parameter to be a function

Feature Use Case

When generating images as per suggestion in the docs here at the bottom of the page:

Optimize and transform images to webp

const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');

module.exports = {
  plugins: [
    new ImageMinimizerPlugin({
      minimizerOptions: {
        plugins: ['pngquant'],
      },
    }),
    new ImageMinimizerPlugin({
      deleteOriginalAssets: false,
      filename: '[path][name].webp',
      minimizerOptions: {
        plugins: ['imagemin-webp'],
      },
    }),
  ],
};

Then the file-loader is being replaced with Asset modules as explained here, so this would be the next thing to add:

module: {
   rules: [
     {
       test: /\.png/,
       type: 'asset/resource'
     }
   ]
 },

Everything works fine with this configuration. That is until you start adding a generator to the rule above.

module: {
   rules: [
     {
      test: /\.png/,
      type: 'asset/resource',
      generator: {
        filename: ({ filename }) => filename.replace('assets/', '')  },
      },
    }
  ]
}

With this rule added the images will start to end up in different subfolders. Due to legacy stuff it might be needed to keep filenames and subfolder intact but only strip the first subdirectory of the paths, ie 'assets/'.

Allowing filename to be a function would give back this control to the user.

Error in Plugin name should be specified

Documentation Is:

  • Missing
  • Needed
  • Confusing
  • Not Sure?
  • Broken

Please Explain in Detail...

Hey,
I'm using Webpack 5 using the Asset Module for images as described in the Asset Management documentation.

Now I added the ImageMinimizerWebpackPlugin.

During compilation I get the error: "Error in Plugin name should be specfied".

When I turn

[
  'svgo',
  {
    plugins: [
      {
        removeViewBox: false,
      },
    ],
  },
],

into

[
  'svgo',
  {
    removeViewBox: false,
  },
],

it works, but it does not seem like the option still does what it's supposed (when I set removeViewBox: true it does not remove the viewBox).
Not a problem in my case though, I don't want it to be removed.

Your Proposal for Changes

I'm not sure if the documentation is broken, or if the plugin does not work with the asset management. But I still wanted to leave a note here, that errors appear when following the documentation for the basic setup.
If anything is missing in this issue, let me know and I'll try to provide it.

options has an unknown property 'minify'. These properties are valid:

Version 2.2.0 following docs to use squoosh

[webpack-cli] Invalid options object. Image Minimizer Plugin has been initialized using an options object that does not match the API schema.
 - options has an unknown property 'minify'. These properties are valid:
   object { test?, include?, exclude?, minimizerOptions?, filter?, severityError?, loader?, maxConcurrency?, filename?, deleteOriginalAssets? }

How to use image-minimizer-webpack-plugin in an Angular application

Documentation Is:

  • [ X] Missing
  • [ X] Needed
  • Confusing
  • Not Sure?

Please Explain in Detail...

I have been trying to install, configure and use image-minimizer-webpack-plugin with an angular 13 application, but i have found no clear, complete and up to date example of how to do this.
Any help would be appreciated.
Thank you

Your Proposal for Changes

An in-range update of eslint-plugin-import is breaking the build 🚨

Version 2.4.0 of eslint-plugin-import just got published.

Branch Build failing 🚨
Dependency eslint-plugin-import
Current Version 2.3.0
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

As eslint-plugin-import is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this 💪

Status Details
  • continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details

Commits

The new version differs by 10 commits.

  • 44ca158 update utils changelog
  • a3728d7 bump eslint-module-utils to v2.1.0
  • 3e29169 bump v2.4.0
  • ea9c92c Merge pull request #737 from kevin940726/master
  • 8f9b403 fix typos, enforce type of array of strings in allow option
  • 95315e0 update CHANGELOG.md
  • 28e1623 eslint-module-utils: filePath in parserOptions (#840)
  • 2f690b4 update CI to build on Node 6+7 (#846)
  • 7d41745 write doc, add two more tests
  • dedfb11 add allow glob for rule no-unassigned-import, fix #671

See the full diff

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

Doesn't seem to work with responsive loader

This is my config file

const ImageminPlugin = require('imagemin-webpack').ImageminWebpackPlugin;
const responsiveSharp = require('responsive-loader/sharp');
const ImageminWebp = require('imagemin-webp');

const config = {
    entry: './src/index.js',
    output: {
        
        filename: '[name].js',
        pathinfo: false
    },
    module: {
        rules: [
            {
                test: /\.(css)$/,
                use: [
                    {
                        loader: 'style-loader',
                    },
                    {
                        loader: "css-loader", // creates style nodes from JS strings
                    }
                ]
            },
            {
                test: /\.(png|jpe?g|svg|bmp|gif|webp)$/,
                use: [
                    {
                        loader: 'url-loader',
                        options: {
                            limit: 10000,
                            name: 'images/[name].[hash].[ext]',
                            fallback: 'responsive-loader',
                            adapter: responsiveSharp
                        }
                    }
                ]
            }
        ]
    },
    plugins: [
        
    ],
}

const imagemin2 = new ImageminPlugin({
    // name: 'imagemin/[name].[hash].webp',
    imageminOptions: {
        plugins: [
            ImageminWebp({
                loseless: true
            })
        ]
    }
});

// config.plugins.push(imagemin);
config.plugins.push(imagemin2);
module.exports =  config;

Add/removing this plugin with responsive-loader doesn't seem to effect image size in any way however if I disable responsive-loader and enable this it does produce minified image.

I am expecting it to minify images that go through responsive loader.

This is my package.json

"devDependencies": {
    "css-loader": "^1.0.0",
    "file-loader": "^2.0.0",
    "imagemin-gifsicle": "^5.2.0",
    "imagemin-jpegtran": "^5.0.2",
    "imagemin-mozjpeg": "^7.0.0",
    "imagemin-optipng": "^5.2.1",
    "imagemin-svgo": "^7.0.0",
    "imagemin-webp": "^4.1.0",
    "imagemin-webpack": "^3.0.0",
    "responsive-loader": "^1.1.0",
    "sharp": "^0.21.0",
    "style-loader": "^0.23.1",
    "url-loader": "^1.1.2",
    "webpack": "^4.26.1",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.1.10"
  },

Generate both PNGs and WEBPs

Hi,
I'm trying to use this plugin to generate, as the issue's name indicates, both PNG and WEBP files, in order to maintain compatibility with older Safari versions that do not support WEBP. I'd like to minify the generated images too, if that's possible.
I'm still using the old plugin notation for easier maintenance but planning to move to the newer asset one soon. Though, it shouldn't change the issue, at least to my knowledge.
Here is my configuration:

new ImageMinimizerPlugin({
  generator: [
    {
      type: "asset",
      implementation: ImageMinimizerPlugin.imageminGenerate,
      options: {
        plugins: ["imagemin-pngquant", "imagemin-webp"],
      },
    },
  ],
}),

Using this configuration, it does generate WEBP imagges but still tries to use PNG in the source code, which are not being generated for some reason.
If I remove imagemin-webp from the plugins list, PNGs are generated.
Am I doing anything wrong?

Thanks in advance and thank you for this amazing plugin!
Been using it since about two years for Safari image optimization alone and it's been flawless so far.

Plugin fails to overwrite images emitted by favicons-webpack-plugin.

Icon emitted by favicons-plugin without imagemin-webpack:

/favicons-3d677750/apple-touch-startup-image-1536x2008.png    122 KiB          [emitted]

Same icon with imagemin-webpack and name set to [path][name].[ext](Not compressed)

/favicons-3d677750/apple-touch-startup-image-1536x2008.png    122 KiB          [emitted]

Same icon but this time name is set to [name].[ext]. (Compressed)

apple-touch-startup-image-1536x2008.png   30.5 KiB          [emitted]

Looks like imagemin-webpack can't overwrite already emitted images by favicons-webpack-plugin

"webpack": "4.41.4"
"imagemin-webpack": "5.1.1"
"imagemin-pngquant": "8.0.0"
"favicons-webpack-plugin": "1.0.2"

exclude sub directory

Hey there! If you need support, help, or advice then this is not the place to ask.
I have such structure:

image

How can i exclude svg folder? (because it processed by another loader)
Oh, here's my loader code:

image

Path to image wrong in css file when use "contenthash".

Bug report

When using[contenthash] for assetModuleFilename like this:

assetModuleFilename: '[name].[contenthash][ext][query]',

The filename of the asset output is not the same as the url in the CSS file.

Actual Behavior

File names are different between CSS url and output files.

image

Expected Behavior

The CSS url use correct file:
image

How Do We Reproduce?

You can download this project and run build to check CSS file.

Please paste the results of npx webpack-cli info here, and mention other relevant information

  System:
    OS: macOS 11.5.2
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Memory: 1.75 GB / 16.00 GB
  Binaries:
    Node: 14.15.4 - /usr/local/bin/node
    Yarn: 1.22.11 - /usr/local/bin/yarn
    npm: 7.24.0 - /usr/local/bin/npm
  Browsers:
    Brave Browser: 93.1.29.79
    Chrome: 93.0.4577.82
    Edge: 93.0.961.52
    Firefox: 92.0
    Safari: 14.1.2
  Packages:
    image-minimizer-webpack-plugin: ^2.2.0 => 2.2.0 
    webpack: ^5.53.0 => 5.53.0 
    webpack-cli: ^4.8.0 => 4.8.0 

imageminWebp supported?

I've been trying to add imagemin-webp package within the plugins section for ImageminPlugin config, but it does not output any .webp images, only .jpg, .png etc files.
Here is my config for your plugin:

const imageMinPlugin = new ImageminPlugin({ imageminOptions: { plugins: [ imageminGifsicle({ interlaced: true, optimizationLevel: 3 }), imageminOptipng({ interlaced: true, optimizationLevel: 3 }), imageminMozjpeg({ quality: 80, progressive: true }), imageminWebp({quality: 50}) ] }, test: /\.(jpe?g|png|gif|svg)$/i });

Typescript types are not correct

Bug report

I am running a webpack.config.ts config file and the types are incompatible.

Actual Behavior

This is copied from the README of this repo.

      new ImageMinimizerWebpackPlugin({
        minimizer: {
          implementation: ImageMinimizerWebpackPlugin.squooshMinify,
          options: {
            encodeOptions: {
              avif: {
                cqLevel: 0
              },
              mozjpeg: {
                quality: 100
              },
              webp: {
                lossless: 1
              }
            }
          }
        }
      })
Type '{ implementation: typeof ImageMinimizerWebpackPlugin.squooshMinify; options: { encodeOptions: { avif: { cqLevel: number; }; mozjpeg: { quality: number; }; webp: { lossless: number; }; }; }; }' is not assignable to type 'Minimizer<unknown> | Minimizer<unknown>[] | undefined'.
  Types of property 'implementation' are incompatible.
    Type 'typeof squooshMinify' is not assignable to type 'TransformerFunction<unknown>'.
      Type 'typeof squooshMinify' is not assignable to type 'BasicTransformerHelpers'.
        The types returned by 'setup()' are incompatible between these types.
          Type 'void' is not assignable to type '{}'.ts(2322)

Expected Behavior

I would expect no typescript errors

How Do We Reproduce?

Use a webpack.config.ts file and the error should be there.

jpg is not rendering as file using imagemin-webp

Situation

webpack version: 5.56.0
image-minimizer-webpack-plugin: ^3.1.2

Hello! I tried to use imagemin-webp. In the first case i took png file and it was ok, in the result i've got a image.webp file. In the second case i took .jpg file and it was rendered like base64 in src attribute but i need a .webp file. How can i do this?

image
image

Thanks!

FATAL Cannot read property 'tapPromise' of undefined

my project is nuxt, and the plugin version is 2.2.0, he will report a error:

` FATAL Cannot read property 'tapPromise' of undefined 10:09:04

at node_modules\image-minimizer-webpack-plugin\dist\index.js:304:39
at SyncHook.eval [as call] (eval at create (node_modules\tapable\lib\HookCodeFactory.js:19:10), :11:1)
at SyncHook.lazyCompileHook (node_modules\tapable\lib\Hook.js:154:20)
at Compiler.newCompilation (node_modules\webpack\lib\Compiler.js:631:26)
at node_modules\webpack\lib\Compiler.js:667:29
at AsyncSeriesHook.eval [as callAsync] (eval at create (node_modules\tapable\lib\HookCodeFactory.js:33:10), :6:1)
at AsyncSeriesHook.lazyCompileHook (node_modules\tapable\lib\Hook.js:154:20)
at Compiler.compile (node_modules\webpack\lib\Compiler.js:662:28)
at node_modules\webpack\lib\Compiler.js:321:11
at Compiler.readRecords (node_modules\webpack\lib\Compiler.js:529:11)
at node_modules\webpack\lib\Compiler.js:318:10
at AsyncSeriesHook.eval [as callAsync] (eval at create (node_modules\tapable\lib\HookCodeFactory.js:33:10), :6:1)
at AsyncSeriesHook.lazyCompileHook (node_modules\tapable\lib\Hook.js:154:20)
at node_modules\webpack\lib\Compiler.js:315:19
at AsyncSeriesHook.eval [as callAsync] (eval at create (node_modules\tapable\lib\HookCodeFactory.js:33:10), :15:1)
at AsyncSeriesHook.lazyCompileHook (node_modules\tapable\lib\Hook.js:154:20)`

How can I use it normally? thanks for help

Documentation: Typo in the squoosh-generator-resize section

Documentation Is:

  • Missing
  • Needed
  • Confusing
  • Not Sure?

Please Explain in Detail...

The documentation for the resize option of the squoosh generator has a typo:

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        generator: [
          {
            // You can apply generator using `?as=webp-100-50`, you can use any name and provide more options
            preset: "webp-100-50",
            implementation: ImageMinimizerPlugin.squooshGenerate,
            options: {
              encodeOptions: {
                resize: {
                  enabled: true,
                  width: 100,
                  height: 50,
                },
                webp: {
                  quality: 90,
                },
              },
            },
          },
        ],
      }),
    ],
  },
};

Your Proposal for Changes

Notice that the resize option is inside the encodeOptions, but it should actually say:

const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
module.exports = {
  optimization: {
    minimizer: [
      "...",
      new ImageMinimizerPlugin({
        generator: [
          {
            // You can apply generator using `?as=webp-100-50`, you can use any name and provide more options
            preset: "webp-100-50",
            implementation: ImageMinimizerPlugin.squooshGenerate,
            options: {
              resize: {
                enabled: true,
                width: 100,
                height: 50,
              },
              encodeOptions: {
                webp: {
                  quality: 90,
                },
              },
            },
          },
        ],
      }),
    ],
  },
};

because utils.js takes the preprocess options for libsquoosh directly from squooshOptions (minifyOptions) and not from squooshOptions.encodeOptions

`deleteOriginalAsset` option do not work in loader

Expected Behavior

We transform the image into a .webp and use deleteOriginalAsset option
We should to get only transformed image.webp

Actual Behavior

We transform the image into a .webp and use deleteOriginalAsset option
We get image.webp and original image

The problem relates to loader in the image-minimizer-webpack-plugin

Cache Minified Images

Repeatedly minifying an image should be avoided. A cache containing hashes of minified files should be saved to disk so it can be checked in to Git and shared across a team.

image doesn't compressed with loader

Compiler Output
screen shot 2018-06-29 at 6 10 23 am

As you see the image size of screenshot.png is around 800KB, no matter what optimization level is used, the image size in build folder is same.

Version Info
webpack : 4.12.0

webpack.config.js

const autoprefixer = require('autoprefixer');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { ImageminWebpackPlugin, imageminLoader } = require('imagemin-webpack');

// Before imagemin
const imageminGifsicle = require('imagemin-gifsicle');
const imageminJpegtran = require('imagemin-jpegtran');
const imageminOptipng = require('imagemin-optipng');
const imageminPngquant = require('imagemin-pngquant');
const imageminSvgo = require('imagemin-svgo');
const imageminManifest = {};

const path = require('path');
const fs = require('fs');

const appDirectory = fs.realpathSync(process.cwd());

function resolveApp(relativePath) {
  return path.resolve(appDirectory, relativePath);
}

const DEV = process.env.NODE_ENV === 'development';

const paths = {
  appSrc: resolveApp('src'),
  appBuild: resolveApp('build'),
  appIndexJs: resolveApp('src/app.js'),
  appNodeModules: resolveApp('node_modules')
};

module.exports = {
  target: 'web',
  mode: DEV ? 'development' : 'production',
  devtool: DEV ? 'cheap-eval-source-map' : 'source-map',
  entry: {
    app: paths.appIndexJs
  },
  output: {
    filename: DEV ? 'bundle.js' : 'bundle.[hash:8].js',
    path: paths.appBuild
  },
  module: {
    rules: [
      // Disabling require.ensure as it's not a standard language
      { parser: { requireEnsure: false } },

      // js loader
      {
        test: /.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader'
        }
      },
      // css loader
      {
        test: /\.(sass|scss|css)$/,
        use: [{
          loader: MiniCssExtractPlugin.loader
        },{
          loader: 'css-loader',
          options: {
            importLoader: 1
          }
        },{
          loader: 'postcss-loader',
          options: {
            ident: 'postcss',
            plugins: () => [
              autoprefixer({
                browsers: [
                  '>1%',
                  'last 4 versions',
                  'Firefox ESR',
                  'not ie < 9',
                ],
              }),
            ],
          }
        },
        {
          loader: 'sass-loader'
        }]
      },

      //img webpack optimization loader
      {
        test: /\.(png|gif|jpe?g|svg)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              emitFile: true,
              useRelativePath: true,
              name: "[name].[ext]",
            }
          },
        ]
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "[name].css",
      chunkFilename: "[id].css"
    }),
    new ImageminWebpackPlugin({
      cache: true,
      bail: false, // Ignore errors on corrupted images
      loader: false,
      imageminOptions: {
        plugins: [
          imageminGifsicle({
            interlaced: true,
            optimizationLevel: 3
          }),
          // imageminOptipng({
          //   interlaced: true,
          //   optimizationLevel: 3
          // }),
          imageminPngquant({
            quality: 10,
            speed: 4,
          }),
          imageminJpegtran({
            progressive: true,
            optimizationLevel: 3
          })
        ]
      },
      manifest: imageminManifest, // This object will contain source and interpolated filenames
      // maxConcurrency: os.cpus().length - 1,
      name: "[hash].[ext]",
      test: /\.(jpe?g|png|gif|svg)$/i,
      include: undefined,
      exclude: undefined
    })
  ],
  performance: {
    hints: false
  }
}

does not work with copy-webpack-plugin

My CopyWebpackPlugin comes before ImageminPlugin as instructed.
The images from CopyWebpackPlugin are nowhere to be found in the build folder, though.
When I remove the ImageminPlugin they are being copied successfully.

Error: Prevent writing to file that only differs in casing or query string from already written file.

  • Operating System: Windows 10 x64 (WSL 2)
  • Node Version: v14.15.4
  • NPM Version: 7.5.4
  • webpack Version: 5.x
  • image-minimizer-webpack-plugin Version: 2.2.0

Expected Behavior

webpack build should just run fine, without an error message because of duplicate file names.

Actual Behavior

webpack build fails with error, the files are generated.

webpack-cli] Error: Prevent writing to file that only differs in casing or query string from already written file.
This will lead to a race-condition and corrupted files on case-insensitive file systems.
[...]/images/test-1.jpg
[...]/images/test-1.jpg

Code

.img-orig {
  background: url("../images/test-1.jpg?size=1140");
}

.img-webp {
  background: url("../images/test-1.jpg?size=1140&format=webp");
}

How Do We Reproduce?

Run the webpack build. Notice the error message.

Add TypeScript definitions

I'm using imagemin-webpack in my webpack configuration, and it would be nice to have type definitions for this loader.

This is fairly easy to add:

  1. Run npm install --save-dev typescript.
  2. Create a tsconfig.json file like:
    {
      "compilerOptions": {
        "target": "ES5",
        "outDir": "types",
        "newLine": "LF",
        "allowJs": true,
        "declaration": true,
        "emitDeclarationOnly": true
      },
      "include": [
        "index.js",
        "src/**/*"
      ],
      "compileOnSave": false
    }
  3. Add "types": "types/index.d.ts" to package.json.
  4. Run npx tsc to generate the declaration files.

(optional: Add an npm script and add some JSDoc comments)

this webpack plugin should use ESM, or indicate incompatibility with ESM

Modification Proposal

https://github.com/imagemin/imagemin-svgo/releases/tag/v10.0.0 requires all modules that import it to support ESM; while v9.0.0 continues to work fine, there should be something added to indicate that imagemin-svgo should not be upgraded until this package is upgraded to ESM as well.

Expected Behavior / Situation

SVG packing and optimization should happen correctly with imagemin-svgo.

Actual Behavior / Situation

Warnings and failed svg packing, because an ESM module cannot be loaded with require() from a cjs module.

WARNING in ./src/client/shared/res/LoadingSpinner-spinner.svg
Module Warning (from ./node_modules/image-minimizer-webpack-plugin/dist/loader.js):
Unknown plugin: imagemin-svgo

Did you forget to install the plugin?
You can install it with:

$ npm install imagemin-svgo --save-dev
$ yarn add imagemin-svgo --dev
 @ ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[1]!./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[7].use[0]!./src/client/shared/LoadingSpinner.vue?vue&type=template&id=440c8cdd&scoped=true 2:0-57 27:21-31
 @ ./src/client/shared/LoadingSpinner.vue?vue&type=template&id=440c8cdd&scoped=true 1:0-232 1:0-232
 @ ./src/client/shared/LoadingSpinner.vue 1:0-87 6:16-22
 @ ./node_modules/ts-loader/index.js??clonedRuleSet-1!./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[7].use[0]!./src/client/admin/AccountLog.vue?vue&type=script&lang=ts
 @ ./src/client/admin/AccountLog.vue?vue&type=script&lang=ts 1:0-202 1:0-202 1:203-394 1:203-394
 @ ./src/client/admin/AccountLog.vue 2:0-61 3:0-56 3:0-56 6:0-13 7:0-16 9:15-21
 @ ./src/client/home.ts

Please paste the results of npx webpack-cli info here, and mention other relevant information

yarn webpack-cli info
yarn run v1.22.5
$ /home/lizf/eve-roster/node_modules/.bin/webpack-cli info

  System:
    OS: Linux 5.11 Ubuntu 20.04.3 LTS (Focal Fossa)
    CPU: (12) x64 AMD Ryzen 5 5600X 6-Core Processor
    Memory: 1.27 GB / 31.29 GB
  Binaries:
    Node: 14.17.6 - /tmp/yarn--1632200084282-0.1678014881235168/node
    Yarn: 1.22.5 - /tmp/yarn--1632200084282-0.1678014881235168/yarn
  Browsers:
    Chrome: beta
    Firefox: 92.0
  Packages:
    clean-webpack-plugin: ^4.0.0 => 4.0.0 
    css-minimizer-webpack-plugin: ^3.0.2 => 3.0.2 
    html-webpack-plugin: ^5.3.2 => 5.3.2 
    html-webpack-pug-plugin: ^3.0.0 => 3.0.0 
    image-minimizer-webpack-plugin: ^2.2.0 => 2.2.0 
    moment-locales-webpack-plugin: ^1.2.0 => 1.2.0 
    terser-webpack-plugin: ^5.2.4 => 5.2.4 
    webpack: ^5.37.1 => 5.38.1 
    webpack-cli: ^4.8.0 => 4.8.0 
    webpack-dev-middleware: ^5.1.0 => 5.1.0 
    webpack-hot-middleware: webpack-contrib/webpack-hot-middleware#webpack5 => 2.25.0 
    webpack-merge: ^5.8.0 => 5.8.0 

Done in 0.36s.

Inline UTF8 SVG URL gets encoded into base64, but the base64 extension is missing

Bug report

Preinlined SVG does not show in browser.

Actual Behavior

A preinlined UTF8 SVG gets encoded correctly into base64 when using ImageMinimizerPlugin.imageminGenerate, but the standard base64 extension is not added to the final output, so the image does not show in browser.

data:image/svg+xml;utf8,[...]

Is this a bug, or am I using the plugin wrong?

Expected Behavior

The transformer should add the standard base64 extension in order for the image to show.

data:image/svg+xml;utf8;base64,[...]

How Do We Reproduce?

  1. Download reproduction gist: https://gist.github.com/patrikjuvonen/8c1bb10b1b9c56e9cdba1f48c99a4c72
  2. Run npm install
  3. Postinstall will automatically run webpack --mode production
  4. See the SVG data URI output at dist/main.css, it does not have the standard base64 extension in it
  5. Open test.html in your browser, you can see a blank screen
  6. Add the standard base64 extension to the data URI manually (data:image/svg+xml;utf8;base64,[...])
  7. Open test.html in your browser again, you can see a checkmark icon on the body element

Please paste the results of npx webpack-cli info here, and mention other relevant information

Test bench 1

  System:
    OS: Linux 5.4 Ubuntu 20.04.3 LTS (Focal Fossa)
    CPU: (2) x64 AMD EPYC 7542 32-Core Processor
    Memory: 343.90 MB / 3.84 GB
  Binaries:
    Node: 16.13.1 - ~/.nvm/versions/node/v16.13.1/bin/node
    npm: 8.3.0 - ~/.nvm/versions/node/v16.13.1/bin/npm
  Packages:
    css-loader: ^6.5.1 => 6.5.1
    image-minimizer-webpack-plugin: ^3.2.0 => 3.2.0
    webpack: ^5.65.0 => 5.65.0
    webpack-cli: ^4.9.1 => 4.9.1 

Test bench 2

  System:
    OS: macOS 12.1
    CPU: (8) arm64 Apple M1
    Memory: 3.56 GB / 16.00 GB
  Binaries:
    Node: 16.13.1 - ~/.nvm/versions/node/v16.13.1/bin/node
    npm: 8.3.0 - ~/.nvm/versions/node/v16.13.1/bin/npm
  Browsers:
    Chrome: 96.0.4664.110
    Firefox: 95.0.2
    Safari: 15.2
  Packages:
    css-loader: ^6.5.1 => 6.5.1
    image-minimizer-webpack-plugin: ^3.2.0 => 3.2.0
    webpack: ^5.65.0 => 5.65.0
    webpack-cli: ^4.9.1 => 4.9.1

Test bench 3

  System:
    OS: Windows 10 10.0.19044
    CPU: (16) x64 Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
    Memory: 23.97 GB / 31.92 GB
  Binaries:
    Node: 16.13.1 - C:\Program Files\nodejs\node.EXE
    npm: 8.3.0 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Chrome: 96.0.4664.110
    Edge: Spartan (44.19041.1266.0), Chromium (96.0.1054.62)
    Internet Explorer: 11.0.19041.1202
  Packages:
    css-loader: ^6.5.1 => 6.5.1
    image-minimizer-webpack-plugin: ^3.2.0 => 3.2.0
    webpack: ^5.65.0 => 5.65.0
    webpack-cli: ^4.9.1 => 4.9.1

Images bug in dev server

Hello! I tried to use this plugin in dev server but there's something strange. I have generators (for .webp and .avif) and i try to require it in HTML (in my case it is .pug but never mind). When i have one require it is ok, but when i have two requires or more - the last require generates image, each previous returns default value (in my case it is .jpg).

Video demonstation:

click

Webpack configuration:

click

An in-range update of imagemin is breaking the build 🚨

Version 5.3.0 of imagemin just got published.

Branch Build failing 🚨
Dependency imagemin
Current Version 5.2.2
Type dependency

This version is covered by your current version range and after updating it in your project the build failed.

imagemin is a direct dependency of this project this is very likely breaking your project right now. If other packages depend on you it’s very likely also breaking them.
I recommend you give this issue a very high priority. I’m sure you can resolve this 💪

Status Details
  • continuous-integration/travis-ci/push The Travis CI build failed Details

Commits

The new version differs by 5 commits0.

  • 986e095 5.3.0
  • 2310105 Minor tweaks
  • 543437f Meta tweaks and bump dependencies
  • 4a8b040 Don't recommend mozjpeg in the readme example (#201)
  • 3e2a9f6 Remove mozjpeg option from the example code

false

See the full diff

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

can you show a sample webpackconfig?

Below is my settings but its not compressing png,jpg even i set the optimizationLevel to any number.

it would really be helpful if you can show a sample of the whole config with how to optimizationLevel.

sorry im a noob in webpack

const { ImageminWebpackPlugin } = require("imagemin-webpack");
const imageminGifsicle = require("imagemin-gifsicle");
const imageminOptipng = require('imagemin-optipng');
const imageminJpegtran = require('imagemin-jpegtran');
module.exports = {
  entry: {
    home: './src/js/home.js',
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'js/[name].bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.(gif|png|jpe?g|svg)$/i,
        use: [
          'file-loader?name=[name].[ext]&outputPath=images/&publicPath=images/',
        ]
      }
    ]
  },
  plugins: [
    new HtmlWebPackPlugin({
      title: 'Custom template',
      template: path.join(__dirname, 'src', 'index.html'),
      excludeChunks: ['about'],
      hash: true,
    }),
    new ImageminWebpackPlugin({
      imageminOptions: {
        plugins: [
          imageminGifsicle({
            interlaced: true,
            optimizationLevel: 3
          }),
          imageminOptipng({
            interlaced: true,
            optimizationLevel: 3
          }),
          imageminJpegtran({
            progressive: true,
            optimizationLevel: 3
          })
        ]
      },
      name: "[name]-[hash].[ext]",
      test: /\.(jpe?g|png|gif|svg)$/i
    })
  ]
}```

Support for processing images using CopyWebpackPlugin doesn't work in v3

Hi -- I'm trying to upgrade to v3, but I can't seem to get the new version to work in concert with the CopyWebpackPlugin.

Basically I'm moving a bunch of pngs into a specific folder and then am converting them to webp.

Here is my current webpack config if that helps any: https://github.dev/gitkraken/vscode-gitlens/blob/15e4f478c3e84c78552c7531dbbbaa926c91ed35/webpack.config.js#L379-L398

Here is a discussion about the prior support:
webpack/webpack#14280 (reply in thread)

Thanks!

SVGO config: deepmerge drop toString

Hi!
thx for imagemin-webpack!

Example config from svgo#674

const imageminOptions = ['svgo', {
  plugins: [{
    cleanupIDs: {
      prefix: {
        toString() {
          this.counter = this.counter || 0;
          return `id-${this.counter++}`;
        }
      }
    }
  }],
}],

But after deepmerge -- toString removed :-(

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.