Skip to content

Commit

Permalink
feat: add svgo implementation (#369)
Browse files Browse the repository at this point in the history
  • Loading branch information
RAX7 authored Nov 1, 2022
1 parent dc0a67a commit 0701188
Show file tree
Hide file tree
Showing 13 changed files with 734 additions and 105 deletions.
206 changes: 156 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ with option `"markdown.extension.toc.levels": "2..6"`
- [Optimize with `imagemin`](#optimize-with-imagemin)
- [Optimize with `squoosh`](#optimize-with-squoosh)
- [Optimize with `sharp`](#optimize-with-sharp)
- [Optimize with `svgo`](#optimize-with-svgo)
- [Advanced setup](#advanced-setup)
- [Query Parameters (only `squoosh` and `sharp` currently)](#query-parameters-only-squoosh-and-sharp-currently)
- [Standalone Loader](#standalone-loader)
Expand All @@ -45,6 +46,7 @@ with option `"markdown.extension.toc.levels": "2..6"`
- [Single minimizer example for `imagemin`](#single-minimizer-example-for-imagemin)
- [Single minimizer example for `squoosh`](#single-minimizer-example-for-squoosh)
- [Single minimizer example for `sharp`](#single-minimizer-example-for-sharp)
- [Single minimizer example for user defined implementation](#single-minimizer-example-for-user-defined-implementation)
- [Multiple minimizers example](#multiple-minimizers-example)
- [Minimizer options](#minimizer-options)
- [`implementation`](#implementation)
Expand Down Expand Up @@ -85,11 +87,12 @@ with option `"markdown.extension.toc.levels": "2..6"`

## Getting Started

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

- [`imagemin`](https://github.com/imagemin/imagemin) - optimize your images by default, since it is stable and works with all types of images
- [`squoosh`](https://github.com/GoogleChromeLabs/squoosh/tree/dev/libsquoosh) - while working in experimental mode with `.jpg`, `.jpeg`, `.png`, `.webp`, `.avif` file types.
- [`sharp`](https://github.com/lovell/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`](https://github.com/svg/svgo) - tool for optimizing SVG vector graphics files. Supports only SVG files minification.

> **Warning**
>
Expand Down Expand Up @@ -121,6 +124,12 @@ npm install image-minimizer-webpack-plugin @squoosh/lib --save-dev
npm install image-minimizer-webpack-plugin sharp --save-dev
```

- [`svgo`](https://github.com/svg/svgo):

```console
npm install image-minimizer-webpack-plugin svgo --save-dev
```

Images can be optimized in two modes:

1. [Lossless](https://en.wikipedia.org/wiki/Lossless_compression) (without loss of quality).
Expand Down Expand Up @@ -330,8 +339,10 @@ module.exports = {
minimizer: {
implementation: ImageMinimizerPlugin.sharpMinify,
options: {
// Your options for `sharp`
// https://sharp.pixelplumbing.com/api-output
encodeOptions: {
// Your options for `sharp`
// https://sharp.pixelplumbing.com/api-output
},
},
},
}),
Expand Down Expand Up @@ -395,6 +406,56 @@ module.exports = {
};
```

### Optimize with [`svgo`](https://github.com/svg/svgo)

```console
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](https://github.com/svg/svgo/tree/main/plugins).

**webpack.config.js**

```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**.
Expand Down Expand Up @@ -727,6 +788,7 @@ Allows to setup default minify function.
- `ImageMinimizerPlugin.imageminMinify`
- `ImageMinimizerPlugin.squooshMinify`
- `ImageMinimizerPlugin.sharpMinify`
- `ImageMinimizerPlugin.svgoMinify`
#### Single minimizer example for `imagemin`
Expand Down Expand Up @@ -825,6 +887,61 @@ module.exports = {
More information and examples [here](https://sharp.pixelplumbing.com/api-output#toformat).
#### Single minimizer example for user defined implementation
**webpack.config.js**
```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.
Expand All @@ -841,47 +958,31 @@ module.exports = {
new ImageMinimizerPlugin({
minimizer: [
{
implementation: ImageMinimizerPlugin.imageminMinify,
// `sharp` will handle all bitmap formats (JPG, PNG, GIF, ...)
implementation: ImageMinimizerPlugin.sharpMinify,

// exclude: /\.(svg)$/i, // exclude SVG if implementation support it. Not required for `sharp`.

options: {
plugins: [
"imagemin-gifsicle",
"imagemin-mozjpeg",
"imagemin-pngquant",
"imagemin-svgo",
],
encodeOptions: {
// Your options for `sharp`
// https://sharp.pixelplumbing.com/api-output
},
},
},
{
implementation: (original, options) => {
let result;

try {
result = minifyAndReturnBuffer(original.data);
} catch (error) {
// Return original input if there was an error
return {
filename: original.filename,
data: original.data,
errors: [error],
warnings: [],
};
}

return {
filename: original.filename,
data: result,
warnings: [],
errors: [],
info: {
// Please always set it to prevent double minification
minimized: true,
// Optional
minimizedBy: ["custom-name-of-minimication"],
},
};
},
// `svgo` will handle vector images (SVG)
implementation: ImageMinimizerPlugin.svgoMinify,
options: {
// Custom 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",
],
},
},
},
],
Expand Down Expand Up @@ -1400,27 +1501,32 @@ module.exports = {
{
// You can apply generator using `?as=webp`, you can use any name and provide more options
preset: "webp",
implementation: (original, options) => {
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 = minifyAndReturnBuffer(original.data);
result = await minifyAndReturnBuffer(original.data);
} catch (error) {
// Return original input if there was an error
return {
filename: original.filename,
data: original.data,
errors: [error],
warnings: [],
};
// Store error and return `null` if there was an error
original.errors.push(error);
return null;
}

return {
filename: original.filename,
data: result,
warnings: [],
errors: [],
warnings: [...original.warnings],
errors: [...original.errors],
info: {
...original.info,
// Please always set it to prevent double minification
generated: true,
// Optional
Expand Down
Loading

0 comments on commit 0701188

Please sign in to comment.