-
Notifications
You must be signed in to change notification settings - Fork 275
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This script is used to minify the public images.
- Loading branch information
1 parent
533f65b
commit 048c851
Showing
2 changed files
with
123 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,3 +5,4 @@ | |
**/node_modules | ||
**/dist | ||
**/storybook-static | ||
bin/imagemin.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
/** | ||
* Module dependencies. | ||
*/ | ||
|
||
const chalk = require('chalk'); | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const sharp = require('sharp'); | ||
|
||
/** | ||
* Constans. | ||
*/ | ||
|
||
const divider = '-'.repeat(200); | ||
const rootDirectory = path.resolve(__dirname, '..'); | ||
const directory = path.join(rootDirectory, 'public', 'assets'); | ||
const maxFileSize = 1048576; // 1MB | ||
|
||
/** | ||
* `logger`. | ||
*/ | ||
|
||
const logger = { | ||
error: message => console.log(chalk.red(message)), | ||
info: message => console.log(chalk.blue(message)), | ||
warn: message => console.log(chalk.yellow(message)) | ||
} | ||
|
||
/** | ||
* `getImageSize`. | ||
*/ | ||
|
||
function getImageSize(filePath) { | ||
return fs.statSync(filePath)?.size; | ||
} | ||
|
||
/** | ||
* `setFormat`. | ||
*/ | ||
|
||
function getImage(filePath, quality) { | ||
const image = sharp(filePath); | ||
const extension = path.extname(filePath).toLowerCase(); | ||
|
||
switch (extension) { | ||
case '.jpg': | ||
case '.jpeg': | ||
return image.jpeg({ quality }); | ||
|
||
case '.png': | ||
return image.png({ compressionLevel: Math.max(1, Math.floor(quality / 10)) }); | ||
|
||
case '.webp': | ||
return image.webp({ quality }); | ||
|
||
default: | ||
logger.warn(`Unsupported file format for: ${filePath}`); | ||
logger.info(divider); | ||
|
||
return null; | ||
} | ||
} | ||
|
||
/** | ||
* `compressImage`. | ||
*/ | ||
|
||
function compressImage(filePath, quality) { | ||
if (quality < 25) { | ||
logger.warn(`Minimum quality reached but file size is still above 1MB for: ${filePath}`); | ||
logger.info(divider); | ||
|
||
return; | ||
} | ||
|
||
const image = getImage(filePath, quality); | ||
const originalSize = getImageSize(filePath); | ||
|
||
if (!image) { | ||
return; | ||
} | ||
|
||
image.toBuffer((err, buffer) => { | ||
if (err) { | ||
logger.error(`Error compressing the image: ${filePath}`); | ||
logger.error(`${err}`); | ||
logger.info(divider); | ||
|
||
return; | ||
} | ||
|
||
fs.writeFileSync(filePath, buffer); | ||
|
||
const compressedSize = getImageSize(filePath); | ||
|
||
if (compressedSize > maxFileSize) { | ||
compressImage(filePath, quality - 5); | ||
} else { | ||
|
||
const compression = ((originalSize - compressedSize) / originalSize * 100).toFixed(2); | ||
|
||
logger.info(`Compressed image replaced: ${filePath}, Compression: ${compression}%`); | ||
logger.info(divider); | ||
} | ||
}); | ||
} | ||
|
||
/** | ||
* Read the directory and compress all images. | ||
*/ | ||
|
||
fs.readdir(directory, (err, files) => { | ||
if (err) { | ||
logger.error(`Error reading the directory: ${err}`); | ||
|
||
return; | ||
} | ||
|
||
files.forEach(file => { | ||
compressImage(path.join(directory, file), 75); | ||
}); | ||
}); |