From 7409e6f16af32f3e0517a00e6d53c4b738240e21 Mon Sep 17 00:00:00 2001 From: Pafcal Date: Thu, 27 Dec 2018 18:04:20 +0200 Subject: [PATCH] Preliminary V3.0.0 with support for webpack-dev-server and path hashes --- package-lock.json | 52 ++++++++++++++++++++++++---------------- package.json | 4 ++-- plugin.js | 61 +++++++++++++++++++++++------------------------ 3 files changed, 64 insertions(+), 53 deletions(-) diff --git a/package-lock.json b/package-lock.json index aa055d9..68259b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,9 +14,9 @@ } }, "@nodelib/fs.stat": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.1.tgz", - "integrity": "sha512-KU/VDjC5RwtDUZiz3d+DHXJF2lp5hB9dn552TXIyptj8SH1vXmR40mG0JgGq03IlYsOgGfcv8xrLpSQ0YUMQdA==" + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==" }, "@sindresorhus/is": { "version": "0.7.0", @@ -1041,15 +1041,15 @@ } }, "fast-glob": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.2.tgz", - "integrity": "sha512-TR6zxCKftDQnUAPvkrCWdBgDq/gbqx8A3ApnBrR5rMvpp6+KMJI0Igw7fkWPgeVK0uhRXTXdvO3O+YP0CaUX2g==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.4.tgz", + "integrity": "sha512-FjK2nCGI/McyzgNtTESqaWP3trPvHyRyoyY70hxjc3oKPNmDe8taohLZpoVKoUjW85tbU5txaYUZCNtVzygl1g==", "requires": { "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.0.1", + "@nodelib/fs.stat": "^1.1.2", "glob-parent": "^3.1.0", "is-glob": "^4.0.0", - "merge2": "^1.2.1", + "merge2": "^1.2.3", "micromatch": "^3.1.10" } }, @@ -1234,7 +1234,7 @@ }, "globby": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.1.tgz", + "resolved": "http://registry.npmjs.org/globby/-/globby-8.0.1.tgz", "integrity": "sha512-oMrYrJERnKBLXNLVTqhm3vPEdJ/b2ZE28xN4YARiix1NOIOBPEpOUnm844K1iu/BkphCaf2WNFwMszv8Soi1pw==", "requires": { "array-union": "^1.0.1", @@ -1355,16 +1355,28 @@ "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==" }, "imagemin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/imagemin/-/imagemin-6.0.0.tgz", - "integrity": "sha512-m4Mxwt2QvCp1F85HXoTungXk0Y6XzuvQGqrK9qEddQfo/7x4aZjRENmyXXfc29ei4Mk55rW002bORG86YM3/aQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/imagemin/-/imagemin-6.1.0.tgz", + "integrity": "sha512-8ryJBL1CN5uSHpiBMX0rJw79C9F9aJqMnjGnrd/1CafegpNuA81RBAAru/jQQEOWlOJJlpRnlcVFF6wq+Ist0A==", "requires": { - "file-type": "^8.1.0", + "file-type": "^10.7.0", "globby": "^8.0.1", "make-dir": "^1.0.0", "p-pipe": "^1.1.0", - "pify": "^3.0.0", + "pify": "^4.0.1", "replace-ext": "^1.0.0" + }, + "dependencies": { + "file-type": { + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-10.7.0.tgz", + "integrity": "sha512-AbaGtdWYYRaVrv2MwL/65myuRJ9j3e79e7etJ79US18QHuVlzJBcQHUH+HxDUoLtbyWRTUfLzLkGXX3pP9kfZg==" + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + } } }, "imagemin-webp": { @@ -1420,7 +1432,7 @@ }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "requires": { "kind-of": "^3.0.2" @@ -1471,7 +1483,7 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "requires": { "kind-of": "^3.0.2" @@ -1744,9 +1756,9 @@ } }, "merge2": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.2.tgz", - "integrity": "sha512-bgM8twH86rWni21thii6WCMQMRMmwqqdW3sGWi9IipnVAszdLXRjwDwAnyrVXo6DuP3AjRMMttZKUB48QWIFGg==" + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz", + "integrity": "sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA==" }, "micromatch": { "version": "3.1.10", @@ -2245,7 +2257,7 @@ }, "safe-regex": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "requires": { "ret": "~0.1.10" diff --git a/package.json b/package.json index fe722e7..cff8761 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "imagemin-webp-webpack-plugin", - "version": "2.0.1", + "version": "3.0.0", "description": "Webpack plugin which converts images to the WebP format while also keeping the original files.", "author": { "name": "Alexandru Pavaloi", @@ -20,7 +20,7 @@ "bugs": "https://github.com/iampava/imagemin-webp-webpack-plugin/issues", "homepage": "https://github.com/iampava/imagemin-webp-webpack-plugin", "dependencies": { - "imagemin": "^6.0.0", + "imagemin": "^6.1.0", "imagemin-webp": "^5.0.0" } } diff --git a/plugin.js b/plugin.js index e6a43ef..e48f35e 100644 --- a/plugin.js +++ b/plugin.js @@ -1,11 +1,13 @@ const imagemin = require('imagemin'); const webp = require('imagemin-webp'); -const fs = require('fs'); + +const GREEN = '\x1b[32m%s\x1b[0m'; +const RED = '\x1b[31m%s\x1b[0m'; class ImageminWebpWebpackPlugin { constructor({ config = [{ - test: /\.(jpe?g|png)$/, + test: /\.(jpe?g|png)/, options: { quality: 75 } @@ -19,42 +21,40 @@ class ImageminWebpWebpackPlugin { } apply(compiler) { - compiler.hooks.afterEmit.tapAsync('ImageminWebpWebpackPlugin', (compilation, cb) => { + compiler.hooks.emit.tapAsync('ImageminWebpWebpackPlugin', (compilation, cb) => { let assetNames = Object.keys(compilation.assets); - let path = compilation.options.output.path; let nrOfImagesFailed = 0; Promise.all(assetNames.map(name => { for (let i = 0; i < this.config.length; i++) { if (this.config[i].test.test(name)) { - let outputFolder = name - .split('/') - .slice(0, -1) - .join('/'); + let nameWithoutExtension = name.split(".").slice(0, -1).join("."); + let currentAsset = compilation.assets[name]; - return imagemin([`${path}/${name}`], `${path}/${outputFolder}`, { + return imagemin.buffer(currentAsset.source(), { plugins: [webp(this.config[i].options)] - }).then(resp => { - let path = resp[0].path; - if (path.indexOf(".webp") === path.length - 5 && path.length >= 5) { - let stats = fs.statSync(path); - let savedKB = Math.round((compilation.assets[name].size() - stats.size) / 1000); - - if (this.detailedLogs) { - console.log('\x1b[32m%s\x1b[0m', `${savedKB} KB saved from ${path}`); - } + }).then((buffer) => { + let savedKB = (currentAsset.size() - buffer.length) / 1000; - return savedKB; - } else { - throw new Error(`ImageminWebpWebpackPlugin: "${name}" wasn't converted, most likely because the conversion would result in a bigger file!`); + if (this.detailedLogs) { + console.log(GREEN, `${savedKB.toFixed(1)} KB saved from '${name}'`); } + + compilation.assets[`${nameWithoutExtension}.webp`] = { + source: () => buffer, + size: () => buffer.length + }; + + return savedKB; }).catch(err => { + let customErr = new Error(`ImageminWebpWebpackPlugin: "${name}" wasn't converted, most likely because the conversion would result in a bigger file!`); + nrOfImagesFailed++; if (this.strict) { - compilation.errors.push(err); + compilation.errors.push(err, customErr); } else if (this.detailedLogs) { - compilation.warnings.push(err); + compilation.warnings.push(err, customErr); } return 0; @@ -65,15 +65,14 @@ class ImageminWebpWebpackPlugin { })).then(savedKBArr => { let totalKBSaved = savedKBArr.reduce((acc, cur) => acc + cur, 0); - console.log( - '\x1b[32m%s\x1b[0m', - `imagemin-webp-webpack-plugin: ${Math.floor(totalKBSaved / 100) / 10} MB saved` - ); + if (totalKBSaved < 100) { + console.log(GREEN, `imagemin-webp-webpack-plugin: ${Math.floor(totalKBSaved)} KB saved`); + } else { + console.log(GREEN, `imagemin-webp-webpack-plugin: ${Math.floor(totalKBSaved / 100) / 10} MB saved`); + } + if (nrOfImagesFailed > 0) { - console.log( - '\x1b[31m%s\x1b[0m', - `imagemin-webp-webpack-plugin: ${nrOfImagesFailed} images failed to convert to webp` - ); + console.log(RED, `imagemin-webp-webpack-plugin: ${nrOfImagesFailed} images failed to convert to webp`); } cb(); });