Repository: webpack-contrib/compression-webpack-plugin
Pull request #163 (2020-05-08 22:42:55)

Refactor improve docs and options
<!--
  HOLY CRAP a Pull Request. We ❤️ those!

  If you remove or skip this template, you'll make the 🐼 sad and the mighty god
  of Github will appear and pile-drive the close button from a great height
  while making animal noises.

  Please place an x (no spaces!) in all [ ] that apply
-->

This PR contains a:

- [ ] **bugfix**
- [ ] new **feature**
- [x] **code refactor**
- [x] **test update** <!-- if bug or feature is checked, this should be too -->
- [ ] **typo fix**
- [x] **metadata update**

### Motivation / Use-Case

Improve options validation + docs

### Breaking Changes

No

### Additional Info

No

codecov[bot]: # [Codecov](https://codecov.io/gh/webpack-contrib/compression-webpack-plugin/pull/163?src=pr&el=h1) Report
> Merging [#163](https://codecov.io/gh/webpack-contrib/compression-webpack-plugin/pull/163?src=pr&el=desc) into [master](https://codecov.io/gh/webpack-contrib/compression-webpack-plugin/commit/778e86685778de538ec16055332e4a31788c0431&el=desc) will **not change** coverage.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/webpack-contrib/compression-webpack-plugin/pull/163/graphs/tree.svg?width=650&height=150&src=pr&token=wLGv0aBxEE)](https://codecov.io/gh/webpack-contrib/compression-webpack-plugin/pull/163?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master     #163   +/-   ##
=======================================
  Coverage   96.71%   96.71%           
=======================================
  Files           4        4           
  Lines         152      152           
  Branches       40       40           
=======================================
  Hits          147      147           
  Misses          5        5           
```



------

[Continue to review full report at Codecov](https://codecov.io/gh/webpack-contrib/compression-webpack-plugin/pull/163?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/webpack-contrib/compression-webpack-plugin/pull/163?src=pr&el=footer). Last update [778e866...2f2d9d2](https://codecov.io/gh/webpack-contrib/compression-webpack-plugin/pull/163?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/README.md b/README.md
index 9cd9751..f88b303 100644
--- a/README.md
+++ b/README.md
@@ -40,12 +40,24 @@ And run `webpack` via your preferred method.
 
 ## Options
 
+|                      Name                       |                   Type                    |      Default       | Description                                                                                                   |
+| :---------------------------------------------: | :---------------------------------------: | :----------------: | :------------------------------------------------------------------------------------------------------------ |
+|               **[`test`](#test)**               | `{String\|RegExp\|Array<String\|RegExp>}` |    `undefined`     | Include all assets that pass test assertion                                                                   |
+|            **[`include`](#include)**            | `{String\|RegExp\|Array<String\|RegExp>}` |    `undefined`     | Include all assets matching any of these conditions                                                           |
+|            **[`exclude`](#exclude)**            | `{String\|RegExp\|Array<String\|RegExp>}` |    `undefined`     | Exclude all assets matching any of these conditions                                                           |
+|          **[`algorithm`](#algorithm)**          |           `{String\|Function}`            |       `gzip`       | The compression algorithm/function                                                                            |
+| **[`compressionOptions`](#compressionoptions)** |                `{Object}`                 |   `{ level: 9 }`   | Compression options for `algorithm`                                                                           |
+|          **[`threshold`](#threshold)**          |                `{Number}`                 |        `0`         | Only assets bigger than this size are processed (in bytes)                                                    |
+|           **[`minRatio`](#minratio)**           |                `{Number}`                 |       `0.8`        | Only assets that compress better than this ratio are processed (`minRatio = Compressed Size / Original Size`) |
+|           **[`filename`](#filename)**           |           `{String\|Function}`            | `[path].gz[query]` | The target asset filename.                                                                                    |
+|              **[`cache`](#cache)**              |                `{Boolean}`                |       `true`       | Enable file caching                                                                                           |
+
 ### `test`
 
 Type: `String|RegExp|Array<String|RegExp>`
 Default: `undefined`
 
-Test to match files against.
+Include all assets that pass test assertion.
 
 **webpack.config.js**
 
@@ -64,7 +76,7 @@ module.exports = {
 Type: `String|RegExp|Array<String|RegExp>`
 Default: `undefined`
 
-Files to include.
+Include all assets matching any of these conditions.
 
 **webpack.config.js**
 
@@ -83,7 +95,7 @@ module.exports = {
 Type: `String|RegExp|Array<String|RegExp>`
 Default: `undefined`
 
-Files to exclude.
+Exclude all assets matching any of these conditions.
 
 **webpack.config.js**
 
@@ -97,53 +109,6 @@ module.exports = {
 };
 ```
 
-### `filename`
-
-Type: `String|Function`
-Default: `[path].gz[query]`
-
-The target asset filename.
-
-#### `String`
-
-`[file]` is replaced with the original asset filename.
-`[path]` is replaced with the path of the original asset.
-`[dir]` is replaced with the directory of the original asset.
-`[name]` is replaced with the filename of the original asset.
-`[ext]` is replaced with the extension of the original asset.
-`[query]` is replaced with the query.
-
-**webpack.config.js**
-
-```js
-module.exports = {
-  plugins: [
-    new CompressionPlugin({
-      filename: '[path].gz[query]',
-    }),
-  ],
-};
-```
-
-#### `Function`
-
-**webpack.config.js**
-
-```js
-module.exports = {
-  plugins: [
-    new CompressionPlugin({
-      filename(info) {
-        // info.file is the original asset filename
-        // info.path is the path of the original asset
-        // info.query is the query
-        return `${info.path}.gz${info.query}`;
-      },
-    }),
-  ],
-};
-```
-
 ### `algorithm`
 
 Type: `String|Function`
@@ -190,9 +155,10 @@ module.exports = {
 Type: `Object`
 Default: `{ level: 9 }`
 
+Compression options for `algorithm`.
+
 If you use custom function for the `algorithm` option, the default value is `{}`.
 
-Compression options.
 You can find all options here [zlib](https://nodejs.org/api/zlib.html#zlib_class_options).
 
 **webpack.config.js**
@@ -248,6 +214,53 @@ module.exports = {
 };
 ```
 
+### `filename`
+
+Type: `String|Function`
+Default: `[path].gz[query]`
+
+The target asset filename.
+
+#### `String`
+
+`[file]` is replaced with the original asset filename.
+`[path]` is replaced with the path of the original asset.
+`[dir]` is replaced with the directory of the original asset.
+`[name]` is replaced with the filename of the original asset.
+`[ext]` is replaced with the extension of the original asset.
+`[query]` is replaced with the query.
+
+**webpack.config.js**
+
+```js
+module.exports = {
+  plugins: [
+    new CompressionPlugin({
+      filename: '[path].gz[query]',
+    }),
+  ],
+};
+```
+
+#### `Function`
+
+**webpack.config.js**
+
+```js
+module.exports = {
+  plugins: [
+    new CompressionPlugin({
+      filename(info) {
+        // info.file is the original asset filename
+        // info.path is the path of the original asset
+        // info.query is the query
+        return `${info.path}.gz${info.query}`;
+      },
+    }),
+  ],
+};
+```
+
 ### `deleteOriginalAssets`
 
 Type: `Boolean`
@@ -272,7 +285,7 @@ module.exports = {
 > ⚠ Ignored in webpack 5! Please use https://webpack.js.org/configuration/other-options/#cache.
 
 Type: `Boolean|String`
-Default: `false`
+Default: `true`
 
 Enable file caching.
 The default path to cache directory: `node_modules/.cache/compression-webpack-plugin`.
@@ -348,7 +361,7 @@ module.exports = {
 
 Node 10.16.0 and later has [native support](https://nodejs.org/api/zlib.html#zlib_zlib_createbrotlicompress_options) for Brotli compression in its zlib module.
 
-We can take advantage of this built-in support for Brotli in Node 11.7.0 and later by just passing in the appropriate `algorithm` to the CompressionPlugin:
+We can take advantage of this built-in support for Brotli in Node 10.16.0 and later by just passing in the appropriate `algorithm` to the CompressionPlugin:
 
 **webpack.config.js**
 
diff --git a/src/options.json b/src/options.json
index 1db2b0b..8f28393 100644
--- a/src/options.json
+++ b/src/options.json
@@ -1,90 +1,66 @@
 {
   "additionalProperties": false,
   "definitions": {
-    "file-conditions": {
+    "Rule": {
+      "description": "Filtering rule as regex or string.",
       "anyOf": [
         {
-          "instanceof": "RegExp"
+          "instanceof": "RegExp",
+          "tsType": "RegExp"
         },
         {
-          "type": "string"
+          "type": "string",
+          "minLength": 1
         }
       ]
-    }
-  },
-  "properties": {
-    "test": {
+    },
+    "Rules": {
+      "description": "Filtering rules.",
       "anyOf": [
         {
-          "$ref": "#/definitions/file-conditions"
-        },
-        {
+          "type": "array",
           "items": {
-            "anyOf": [
+            "description": "A rule condition.",
+            "oneOf": [
               {
-                "$ref": "#/definitions/file-conditions"
+                "$ref": "#/definitions/Rule"
               }
             ]
-          },
-          "type": "array"
-        }
-      ]
-    },
-    "include": {
-      "anyOf": [
-        {
-          "$ref": "#/definitions/file-conditions"
+          }
         },
         {
-          "items": {
-            "anyOf": [
-              {
-                "$ref": "#/definitions/file-conditions"
-              }
-            ]
-          },
-          "type": "array"
+          "$ref": "#/definitions/Rule"
         }
       ]
-    },
-    "exclude": {
-      "anyOf": [
-        {
-          "$ref": "#/definitions/file-conditions"
-        },
+    }
+  },
+  "properties": {
+    "test": {
+      "description": "Include all assets that pass test assertion.",
+      "oneOf": [
         {
-          "items": {
-            "anyOf": [
-              {
-                "$ref": "#/definitions/file-conditions"
-              }
-            ]
-          },
-          "type": "array"
+          "$ref": "#/definitions/Rules"
         }
       ]
     },
-    "cache": {
-      "anyOf": [
-        {
-          "type": "boolean"
-        },
+    "include": {
+      "description": "Include all assets matching any of these conditions.",
+      "oneOf": [
         {
-          "type": "string"
+          "$ref": "#/definitions/Rules"
         }
       ]
     },
-    "filename": {
-      "anyOf": [
-        {
-          "type": "string"
-        },
+    "exclude": {
+      "description": "Exclude all assets matching any of these conditions.",
+      "oneOf": [
         {
-          "instanceof": "Function"
+          "$ref": "#/definitions/Rules"
         }
       ]
     },
     "algorithm": {
+      "description": "The compression algorithm/function.",
       "anyOf": [
         {
           "type": "string"
@@ -95,17 +71,43 @@
       ]
     },
     "compressionOptions": {
+      "description": "Compression options for `algorithm`.",
       "additionalProperties": true,
       "type": "object"
     },
     "threshold": {
+      "description": "Only assets bigger than this size are processed. In bytes.",
       "type": "number"
     },
     "minRatio": {
+      "description": "Only assets that compress better than this ratio are processed (`minRatio = Compressed Size / Original Size`).",
       "type": "number"
     },
     "deleteOriginalAssets": {
+      "description": "Whether to delete the original assets or not.",
       "type": "boolean"
+    },
+    "filename": {
+      "description": "The target asset filename.",
+      "anyOf": [
+        {
+          "type": "string"
+        },
+        {
+          "instanceof": "Function"
+        }
+      ]
+    },
+    "cache": {
+      "description": "Enable file caching. Ignored in webpack 5, for webpack 5 please use https://webpack.js.org/configuration/other-options/#cache.",
+      "anyOf": [
+        {
+          "type": "boolean"
+        },
+        {
+          "type": "string"
+        }
+      ]
     }
   },
   "type": "object"


Test patch:
diff --git a/test/__snapshots__/validate-options.test.js.snap.webpack4 b/test/__snapshots__/validate-options.test.js.snap.webpack4
index cee0adf..eac0be6 100644
--- a/test/__snapshots__/validate-options.test.js.snap.webpack4
+++ b/test/__snapshots__/validate-options.test.js.snap.webpack4
@@ -4,6 +4,7 @@ exports[`validate options should throw an error on the "algorithm" option with "
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.algorithm should be one of these:
    string | function
+   -> The compression algorithm/function.
    Details:
     * options.algorithm should be a string.
     * options.algorithm should be an instance of function."
@@ -13,6 +14,7 @@ exports[`validate options should throw an error on the "cache" option with "() =
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.cache should be one of these:
    boolean | string
+   -> Enable file caching. Ignored in webpack 5, for webpack 5 please use https://webpack.js.org/configuration/other-options/#cache.
    Details:
     * options.cache should be a boolean.
     * options.cache should be a string."
@@ -21,56 +23,65 @@ exports[`validate options should throw an error on the "cache" option with "() =
 exports[`validate options should throw an error on the "compressionOptions" option with "1024" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.compressionOptions should be an object:
-   object { … }"
+   object { … }
+   -> Compression options for \`algorithm\`."
 `;
 
 exports[`validate options should throw an error on the "deleteOriginalAssets" option with "true" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
- - options.deleteOriginalAssets should be a boolean."
+ - options.deleteOriginalAssets should be a boolean.
+   -> Whether to delete the original assets or not."
 `;
 
 exports[`validate options should throw an error on the "exclude" option with "[{},"foo",true]" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.exclude should be one of these:
-   RegExp | string | [RegExp | string, ...]
+   [RegExp | non-empty string, ...] | RegExp | non-empty string
+   -> Filtering rules.
    Details:
     * options.exclude[2] should be one of these:
-      RegExp | string
+      RegExp | non-empty string
+      -> Filtering rule as regex or string.
       Details:
        * options.exclude[2] should be an instance of RegExp.
-       * options.exclude[2] should be a string."
+       * options.exclude[2] should be a non-empty string."
 `;
 
 exports[`validate options should throw an error on the "exclude" option with "[true]" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.exclude should be one of these:
-   RegExp | string | [RegExp | string, ...]
+   [RegExp | non-empty string, ...] | RegExp | non-empty string
+   -> Filtering rules.
    Details:
     * options.exclude[0] should be one of these:
-      RegExp | string
+      RegExp | non-empty string
+      -> Filtering rule as regex or string.
       Details:
        * options.exclude[0] should be an instance of RegExp.
-       * options.exclude[0] should be a string."
+       * options.exclude[0] should be a non-empty string."
 `;
 
 exports[`validate options should throw an error on the "exclude" option with "true" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.exclude should be one of these:
-   RegExp | string | [RegExp | string, ...]
+   [RegExp | non-empty string, ...] | RegExp | non-empty string
+   -> Filtering rules.
    Details:
+    * options.exclude should be an array:
+      [RegExp | non-empty string, ...]
     * options.exclude should be one of these:
-      RegExp | string
+      RegExp | non-empty string
+      -> Filtering rule as regex or string.
       Details:
        * options.exclude should be an instance of RegExp.
-       * options.exclude should be a string.
-    * options.exclude should be an array:
-      [RegExp | string, ...]"
+       * options.exclude should be a non-empty string."
 `;
 
 exports[`validate options should throw an error on the "filename" option with "true" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.filename should be one of these:
    string | function
+   -> The target asset filename.
    Details:
     * options.filename should be a string.
     * options.filename should be an instance of function."
@@ -79,133 +90,147 @@ exports[`validate options should throw an error on the "filename" option with "t
 exports[`validate options should throw an error on the "include" option with "[{},"foo",true]" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.include should be one of these:
-   RegExp | string | [RegExp | string, ...]
+   [RegExp | non-empty string, ...] | RegExp | non-empty string
+   -> Filtering rules.
    Details:
     * options.include[2] should be one of these:
-      RegExp | string
+      RegExp | non-empty string
+      -> Filtering rule as regex or string.
       Details:
        * options.include[2] should be an instance of RegExp.
-       * options.include[2] should be a string."
+       * options.include[2] should be a non-empty string."
 `;
 
 exports[`validate options should throw an error on the "include" option with "[true]" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.include should be one of these:
-   RegExp | string | [RegExp | string, ...]
+   [RegExp | non-empty string, ...] | RegExp | non-empty string
+   -> Filtering rules.
    Details:
     * options.include[0] should be one of these:
-      RegExp | string
+      RegExp | non-empty string
+      -> Filtering rule as regex or string.
       Details:
        * options.include[0] should be an instance of RegExp.
-       * options.include[0] should be a string."
+       * options.include[0] should be a non-empty string."
 `;
 
 exports[`validate options should throw an error on the "include" option with "true" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.include should be one of these:
-   RegExp | string | [RegExp | string, ...]
+   [RegExp | non-empty string, ...] | RegExp | non-empty string
+   -> Filtering rules.
    Details:
+    * options.include should be an array:
+      [RegExp | non-empty string, ...]
     * options.include should be one of these:
-      RegExp | string
+      RegExp | non-empty string
+      -> Filtering rule as regex or string.
       Details:
        * options.include should be an instance of RegExp.
-       * options.include should be a string.
-    * options.include should be an array:
-      [RegExp | string, ...]"
+       * options.include should be a non-empty string."
 `;
 
 exports[`validate options should throw an error on the "minRatio" option with "0.8" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
- - options.minRatio should be a number."
+ - options.minRatio should be a number.
+   -> Only assets that compress better than this ratio are processed (\`minRatio = Compressed Size / Original Size\`)."
 `;
 
 exports[`validate options should throw an error on the "test" option with "[{},"foo",true]" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.test should be one of these:
-   RegExp | string | [RegExp | string, ...]
+   [RegExp | non-empty string, ...] | RegExp | non-empty string
+   -> Filtering rules.
    Details:
     * options.test[2] should be one of these:
-      RegExp | string
+      RegExp | non-empty string
+      -> Filtering rule as regex or string.
       Details:
        * options.test[2] should be an instance of RegExp.
-       * options.test[2] should be a string."
+       * options.test[2] should be a non-empty string."
 `;
 
 exports[`validate options should throw an error on the "test" option with "[true]" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.test should be one of these:
-   RegExp | string | [RegExp | string, ...]
+   [RegExp | non-empty string, ...] | RegExp | non-empty string
+   -> Filtering rules.
    Details:
     * options.test[0] should be one of these:
-      RegExp | string
+      RegExp | non-empty string
+      -> Filtering rule as regex or string.
       Details:
        * options.test[0] should be an instance of RegExp.
-       * options.test[0] should be a string."
+       * options.test[0] should be a non-empty string."
 `;
 
 exports[`validate options should throw an error on the "test" option with "true" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.test should be one of these:
-   RegExp | string | [RegExp | string, ...]
+   [RegExp | non-empty string, ...] | RegExp | non-empty string
+   -> Filtering rules.
    Details:
+    * options.test should be an array:
+      [RegExp | non-empty string, ...]
     * options.test should be one of these:
-      RegExp | string
+      RegExp | non-empty string
+      -> Filtering rule as regex or string.
       Details:
        * options.test should be an instance of RegExp.
-       * options.test should be a string.
-    * options.test should be an array:
-      [RegExp | string, ...]"
+       * options.test should be a non-empty string."
 `;
 
 exports[`validate options should throw an error on the "threshold" option with "1024" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
- - options.threshold should be a number."
+ - options.threshold should be a number.
+   -> Only assets bigger than this size are processed. In bytes."
 `;
 
 exports[`validate options should throw an error on the "unknown" option with "/test/" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options has an unknown property 'unknown'. These properties are valid:
-   object { test?, include?, exclude?, cache?, filename?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets? }"
+   object { test?, include?, exclude?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets?, filename?, cache? }"
 `;
 
 exports[`validate options should throw an error on the "unknown" option with "[]" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options has an unknown property 'unknown'. These properties are valid:
-   object { test?, include?, exclude?, cache?, filename?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets? }"
+   object { test?, include?, exclude?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets?, filename?, cache? }"
 `;
 
 exports[`validate options should throw an error on the "unknown" option with "{"foo":"bar"}" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options has an unknown property 'unknown'. These properties are valid:
-   object { test?, include?, exclude?, cache?, filename?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets? }"
+   object { test?, include?, exclude?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets?, filename?, cache? }"
 `;
 
 exports[`validate options should throw an error on the "unknown" option with "{}" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options has an unknown property 'unknown'. These properties are valid:
-   object { test?, include?, exclude?, cache?, filename?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets? }"
+   object { test?, include?, exclude?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets?, filename?, cache? }"
 `;
 
 exports[`validate options should throw an error on the "unknown" option with "1" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options has an unknown property 'unknown'. These properties are valid:
-   object { test?, include?, exclude?, cache?, filename?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets? }"
+   object { test?, include?, exclude?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets?, filename?, cache? }"
 `;
 
 exports[`validate options should throw an error on the "unknown" option with "false" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options has an unknown property 'unknown'. These properties are valid:
-   object { test?, include?, exclude?, cache?, filename?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets? }"
+   object { test?, include?, exclude?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets?, filename?, cache? }"
 `;
 
 exports[`validate options should throw an error on the "unknown" option with "test" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options has an unknown property 'unknown'. These properties are valid:
-   object { test?, include?, exclude?, cache?, filename?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets? }"
+   object { test?, include?, exclude?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets?, filename?, cache? }"
 `;
 
 exports[`validate options should throw an error on the "unknown" option with "true" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options has an unknown property 'unknown'. These properties are valid:
-   object { test?, include?, exclude?, cache?, filename?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets? }"
+   object { test?, include?, exclude?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets?, filename?, cache? }"
 `;
diff --git a/test/__snapshots__/validate-options.test.js.snap.webpack5 b/test/__snapshots__/validate-options.test.js.snap.webpack5
index cee0adf..eac0be6 100644
--- a/test/__snapshots__/validate-options.test.js.snap.webpack5
+++ b/test/__snapshots__/validate-options.test.js.snap.webpack5
@@ -4,6 +4,7 @@ exports[`validate options should throw an error on the "algorithm" option with "
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.algorithm should be one of these:
    string | function
+   -> The compression algorithm/function.
    Details:
     * options.algorithm should be a string.
     * options.algorithm should be an instance of function."
@@ -13,6 +14,7 @@ exports[`validate options should throw an error on the "cache" option with "() =
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.cache should be one of these:
    boolean | string
+   -> Enable file caching. Ignored in webpack 5, for webpack 5 please use https://webpack.js.org/configuration/other-options/#cache.
    Details:
     * options.cache should be a boolean.
     * options.cache should be a string."
@@ -21,56 +23,65 @@ exports[`validate options should throw an error on the "cache" option with "() =
 exports[`validate options should throw an error on the "compressionOptions" option with "1024" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.compressionOptions should be an object:
-   object { … }"
+   object { … }
+   -> Compression options for \`algorithm\`."
 `;
 
 exports[`validate options should throw an error on the "deleteOriginalAssets" option with "true" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
- - options.deleteOriginalAssets should be a boolean."
+ - options.deleteOriginalAssets should be a boolean.
+   -> Whether to delete the original assets or not."
 `;
 
 exports[`validate options should throw an error on the "exclude" option with "[{},"foo",true]" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.exclude should be one of these:
-   RegExp | string | [RegExp | string, ...]
+   [RegExp | non-empty string, ...] | RegExp | non-empty string
+   -> Filtering rules.
    Details:
     * options.exclude[2] should be one of these:
-      RegExp | string
+      RegExp | non-empty string
+      -> Filtering rule as regex or string.
       Details:
        * options.exclude[2] should be an instance of RegExp.
-       * options.exclude[2] should be a string."
+       * options.exclude[2] should be a non-empty string."
 `;
 
 exports[`validate options should throw an error on the "exclude" option with "[true]" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.exclude should be one of these:
-   RegExp | string | [RegExp | string, ...]
+   [RegExp | non-empty string, ...] | RegExp | non-empty string
+   -> Filtering rules.
    Details:
     * options.exclude[0] should be one of these:
-      RegExp | string
+      RegExp | non-empty string
+      -> Filtering rule as regex or string.
       Details:
        * options.exclude[0] should be an instance of RegExp.
-       * options.exclude[0] should be a string."
+       * options.exclude[0] should be a non-empty string."
 `;
 
 exports[`validate options should throw an error on the "exclude" option with "true" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.exclude should be one of these:
-   RegExp | string | [RegExp | string, ...]
+   [RegExp | non-empty string, ...] | RegExp | non-empty string
+   -> Filtering rules.
    Details:
+    * options.exclude should be an array:
+      [RegExp | non-empty string, ...]
     * options.exclude should be one of these:
-      RegExp | string
+      RegExp | non-empty string
+      -> Filtering rule as regex or string.
       Details:
        * options.exclude should be an instance of RegExp.
-       * options.exclude should be a string.
-    * options.exclude should be an array:
-      [RegExp | string, ...]"
+       * options.exclude should be a non-empty string."
 `;
 
 exports[`validate options should throw an error on the "filename" option with "true" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.filename should be one of these:
    string | function
+   -> The target asset filename.
    Details:
     * options.filename should be a string.
     * options.filename should be an instance of function."
@@ -79,133 +90,147 @@ exports[`validate options should throw an error on the "filename" option with "t
 exports[`validate options should throw an error on the "include" option with "[{},"foo",true]" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.include should be one of these:
-   RegExp | string | [RegExp | string, ...]
+   [RegExp | non-empty string, ...] | RegExp | non-empty string
+   -> Filtering rules.
    Details:
     * options.include[2] should be one of these:
-      RegExp | string
+      RegExp | non-empty string
+      -> Filtering rule as regex or string.
       Details:
        * options.include[2] should be an instance of RegExp.
-       * options.include[2] should be a string."
+       * options.include[2] should be a non-empty string."
 `;
 
 exports[`validate options should throw an error on the "include" option with "[true]" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.include should be one of these:
-   RegExp | string | [RegExp | string, ...]
+   [RegExp | non-empty string, ...] | RegExp | non-empty string
+   -> Filtering rules.
    Details:
     * options.include[0] should be one of these:
-      RegExp | string
+      RegExp | non-empty string
+      -> Filtering rule as regex or string.
       Details:
        * options.include[0] should be an instance of RegExp.
-       * options.include[0] should be a string."
+       * options.include[0] should be a non-empty string."
 `;
 
 exports[`validate options should throw an error on the "include" option with "true" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.include should be one of these:
-   RegExp | string | [RegExp | string, ...]
+   [RegExp | non-empty string, ...] | RegExp | non-empty string
+   -> Filtering rules.
    Details:
+    * options.include should be an array:
+      [RegExp | non-empty string, ...]
     * options.include should be one of these:
-      RegExp | string
+      RegExp | non-empty string
+      -> Filtering rule as regex or string.
       Details:
        * options.include should be an instance of RegExp.
-       * options.include should be a string.
-    * options.include should be an array:
-      [RegExp | string, ...]"
+       * options.include should be a non-empty string."
 `;
 
 exports[`validate options should throw an error on the "minRatio" option with "0.8" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
- - options.minRatio should be a number."
+ - options.minRatio should be a number.
+   -> Only assets that compress better than this ratio are processed (\`minRatio = Compressed Size / Original Size\`)."
 `;
 
 exports[`validate options should throw an error on the "test" option with "[{},"foo",true]" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.test should be one of these:
-   RegExp | string | [RegExp | string, ...]
+   [RegExp | non-empty string, ...] | RegExp | non-empty string
+   -> Filtering rules.
    Details:
     * options.test[2] should be one of these:
-      RegExp | string
+      RegExp | non-empty string
+      -> Filtering rule as regex or string.
       Details:
        * options.test[2] should be an instance of RegExp.
-       * options.test[2] should be a string."
+       * options.test[2] should be a non-empty string."
 `;
 
 exports[`validate options should throw an error on the "test" option with "[true]" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.test should be one of these:
-   RegExp | string | [RegExp | string, ...]
+   [RegExp | non-empty string, ...] | RegExp | non-empty string
+   -> Filtering rules.
    Details:
     * options.test[0] should be one of these:
-      RegExp | string
+      RegExp | non-empty string
+      -> Filtering rule as regex or string.
       Details:
        * options.test[0] should be an instance of RegExp.
-       * options.test[0] should be a string."
+       * options.test[0] should be a non-empty string."
 `;
 
 exports[`validate options should throw an error on the "test" option with "true" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options.test should be one of these:
-   RegExp | string | [RegExp | string, ...]
+   [RegExp | non-empty string, ...] | RegExp | non-empty string
+   -> Filtering rules.
    Details:
+    * options.test should be an array:
+      [RegExp | non-empty string, ...]
     * options.test should be one of these:
-      RegExp | string
+      RegExp | non-empty string
+      -> Filtering rule as regex or string.
       Details:
        * options.test should be an instance of RegExp.
-       * options.test should be a string.
-    * options.test should be an array:
-      [RegExp | string, ...]"
+       * options.test should be a non-empty string."
 `;
 
 exports[`validate options should throw an error on the "threshold" option with "1024" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
- - options.threshold should be a number."
+ - options.threshold should be a number.
+   -> Only assets bigger than this size are processed. In bytes."
 `;
 
 exports[`validate options should throw an error on the "unknown" option with "/test/" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options has an unknown property 'unknown'. These properties are valid:
-   object { test?, include?, exclude?, cache?, filename?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets? }"
+   object { test?, include?, exclude?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets?, filename?, cache? }"
 `;
 
 exports[`validate options should throw an error on the "unknown" option with "[]" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options has an unknown property 'unknown'. These properties are valid:
-   object { test?, include?, exclude?, cache?, filename?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets? }"
+   object { test?, include?, exclude?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets?, filename?, cache? }"
 `;
 
 exports[`validate options should throw an error on the "unknown" option with "{"foo":"bar"}" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options has an unknown property 'unknown'. These properties are valid:
-   object { test?, include?, exclude?, cache?, filename?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets? }"
+   object { test?, include?, exclude?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets?, filename?, cache? }"
 `;
 
 exports[`validate options should throw an error on the "unknown" option with "{}" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options has an unknown property 'unknown'. These properties are valid:
-   object { test?, include?, exclude?, cache?, filename?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets? }"
+   object { test?, include?, exclude?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets?, filename?, cache? }"
 `;
 
 exports[`validate options should throw an error on the "unknown" option with "1" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options has an unknown property 'unknown'. These properties are valid:
-   object { test?, include?, exclude?, cache?, filename?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets? }"
+   object { test?, include?, exclude?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets?, filename?, cache? }"
 `;
 
 exports[`validate options should throw an error on the "unknown" option with "false" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options has an unknown property 'unknown'. These properties are valid:
-   object { test?, include?, exclude?, cache?, filename?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets? }"
+   object { test?, include?, exclude?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets?, filename?, cache? }"
 `;
 
 exports[`validate options should throw an error on the "unknown" option with "test" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options has an unknown property 'unknown'. These properties are valid:
-   object { test?, include?, exclude?, cache?, filename?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets? }"
+   object { test?, include?, exclude?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets?, filename?, cache? }"
 `;
 
 exports[`validate options should throw an error on the "unknown" option with "true" value 1`] = `
 "Invalid options object. Compression Plugin has been initialized using an options object that does not match the API schema.
  - options has an unknown property 'unknown'. These properties are valid:
-   object { test?, include?, exclude?, cache?, filename?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets? }"
+   object { test?, include?, exclude?, algorithm?, compressionOptions?, threshold?, minRatio?, deleteOriginalAssets?, filename?, cache? }"
 `;