Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add feature to skip unchanged images during refresh #76

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

* Unreleased | 14/03.2022
- added `skipUnchanged` option

* V3.3.6 | 19/07.2021
- added support for Webpack 5 (https://github.com/iampava/imagemin-webp-webpack-plugin/issues/38)

Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,13 @@ By default the webpack build will fail if any of the images that match your RegE

This option tells the plugin to not crash the build and keep going :)

#### skipUnchanged

Type: `boolean`<br>
Default: `false`

If enabled, unchanged images are skipped during fast-refresh, and only new images are converted.

## Compatibility & known issues

Recently we updated this plugin to make it compatible with **webpack 5**. Originally it was built for **webpack 4** and earlier versions, so I expect it would be compatible no matter the project :)
Expand Down
30 changes: 29 additions & 1 deletion plugin.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const imagemin = require('imagemin');
const webp = require('imagemin-webp');
const gif2webp = require('imagemin-gif2webp');
const crypto = require('crypto');

const GREEN = '\x1b[32m%s\x1b[0m';
const RED = '\x1b[31m%s\x1b[0m';
Expand All @@ -18,19 +19,24 @@ class ImageminWebpWebpackPlugin {
overrideExtension = true,
detailedLogs = false,
strict = true,
silent = false
silent = false,
skipUnchanged = false,
} = {}) {
this.config = config;
this.detailedLogs = detailedLogs;
this.strict = strict;
this.overrideExtension = overrideExtension;
this.silent = silent;
this.skipUnchanged = skipUnchanged;
this.sourceVersions = {};
this.savedKBs = {};
}

apply(compiler) {
const onEmit = (compilation, cb) => {
let assetNames = Object.keys(compilation.assets);
let nrOfImagesFailed = 0;
let nrOfImagesSkipped = 0;

if (this.silent && this.detailedLogs) {
compilation.warnings.push(new Error(`ImageminWebpWebpackPlugin: both the 'silent' and 'detailedLogs' options are true. Overriding 'detailedLogs' and disabling all console output.`));
Expand All @@ -51,6 +57,20 @@ class ImageminWebpWebpackPlugin {

let currentAsset = compilation.assets[name];

let hash = undefined;
if (this.skipUnchanged) {
hash = crypto.createHash('sha256').update(currentAsset.source()).digest('hex');

if (this.sourceVersions[outputName] === hash) {
nrOfImagesSkipped++;
if (this.detailedLogs && !this.silent) {
console.log(GREEN, `Unchanged and skipped: '${name}'`);
}
return Promise.resolve(this.savedKBs[hash] ?? 0);
}
this.sourceVersions[outputName] = hash;
}

return imagemin
.buffer(currentAsset.source(), {
plugins: [
Expand All @@ -66,6 +86,11 @@ class ImageminWebpWebpackPlugin {
}

emitAsset(outputName, buffer, compilation);

if (this.skipUnchanged && hash !== undefined) {
this.savedKBs[hash] = savedKB;
}

return savedKB;
})
.catch(err => {
Expand Down Expand Up @@ -95,6 +120,9 @@ class ImageminWebpWebpackPlugin {
console.log(GREEN, `imagemin-webp-webpack-plugin: ${Math.floor(totalKBSaved / 100) / 10} MB saved`);
}

if (nrOfImagesSkipped > 0) {
console.log(GREEN, `imagemin-webp-webpack-plugin: ${nrOfImagesSkipped} images were unchanged and skipped`);
}
if (nrOfImagesFailed > 0) {
console.log(RED, `imagemin-webp-webpack-plugin: ${nrOfImagesFailed} images failed to convert to webp`);
}
Expand Down