[Optimization] Automating image compression with imagemin
📎 Installing Node.js / npm First, you need to install Node.js and npm. Node.js npm install
📎 Creating package.json npm init -y
💡 -y: Creates a package.json with default values.
📌 Installing imagemin npm install imagemin
📌 Installing imagemin-sharp
npm install imagemin-sharp --save
📌 Creating a JavaScript file for image compression Create a JS file that will run imagemin.
import imagemin from 'imagemin';
import imageminSharp from 'imagemin-sharp';
const MAX_SIZE = 1920; // Maximum width size for images
async function optimizeImages(folderName) {
const inputPath = 'imgs/*.{jpg,png}'; // Path to the folder for image compression
const outputPath = 'optimized'; // Path to save compressed images
const files = await imagemin([inputPath], {
destination: outputPath,
plugins: [
imageminSharp({
chainSharp: async (sharp) => {
const meta = await sharp.metadata();
if (meta.width > MAX_SIZE) {
return sharp.resize({ width: MAX_SIZE }); // Resize images larger than 1920 px to 1920 px
}
return sharp;
},
}),
],
});
console.log('✨ Image optimization COMPLETE ✨');
}
⭐️ Improvements There were several issues with the initial implementation. It’s difficult to change image paths manually in a real work environment.
➡️ Overwrite images by specifying the same input and output paths.
Managing image folders per project can be cumbersome as paths need to be changed manually. ➡️ Allow the folder name to be specified in the build command to optimize images in that folder.
Resizing images that exceed the MAX_SIZE value could affect the actual display. ➡️ Optimize without resizing and show a warning message for images exceeding MAX_SIZE.
After several iterations, the code was improved as follows:
import imagemin from 'imagemin';
import imageminSharp from 'imagemin-sharp';
const MAX_SIZE = 5000;
async function optimizeImages(folderName) {
const INPUT = `imgs/${folderName}/*.{jpg,png}`;
const OUTPUT = `imgs/${folderName}`;
const files = await imagemin([INPUT], {
destination: OUTPUT,
plugins: [
imageminSharp({
chainSharp: async (sharp) => {
const meta = await sharp.metadata();
if (meta.width > MAX_SIZE) {
console.warn(`🚨 Warning: An image exceeds the width of ${MAX_SIZE} px.`);
return sharp;
}
return sharp;
},
}),
],
});
console.log(`✨ Image compression for ${folderName} is complete. ✨`);
}
if (process.argv.length >= 3) {
const folderName = process.argv[2];
optimizeImages(folderName).catch((error) => {
console.error(`Error optimizing images for ${folderName}:`, error);
});
} else {
console.error('Error: Please provide the folder name as an argument.');
}
📌 Modifying package.json Once the code is complete, add the execution command and packages to package.json.
{
"scripts": { // Execution commands
"imgbuild": "node imgbuild.js"
},
"dependencies": { // Adding packages
"imagemin": "^8.0.1",
"imagemin-sharp": "^1.0.6"
}
}
🚨 Warning: If you encounter the error "To load an ES module" This error occurs when using ES modules in Node.js.
📎 The simplest solution Add type: module
to package.json.
{
...
"type": "module", // Add this line
"scripts": {
"imgopt": "node imgopt.js"
},
"dependencies": {
"imagemin": "^8.0.1",
"imagemin-sharp": "^1.0.6"
}
}
📎 If you cannot add type module due to conflicts in the existing development environment Rewrite the code in CommonJS format or change the file extension to .mjs.
If you choose to change the extension to .mjs, also modify the execution command in package.json.
{
...
"scripts": {
"imgopt": "node imgopt.mjs"
},
"dependencies": {
"imagemin": "^8.0.1",
"imagemin-sharp": "^1.0.6"
}
}
📌 Execution Run the command npm run imgopt imgopt_test
. When you execute the specified command, image compression will be completed!
🚧 Caution Verify whether images exceeding MAX_SIZE are necessary or if unnecessarily large images are being used. Once optimized, images cannot be reduced further by running the optimization build again.
👏🏻 Conclusion
🐱: Images take up more space than expected. Let’s compress and optimize them to make a significant impact!