5 min read
Table of Contents:
NodeJS can help you automate simple tasks. Being a web developer, you can achieve the same goals as other programming languages without having to learn them.
Much like the previous article of Automation with Python, NodeJS can be used to automate simple tasks for you. The next task I thought would be great is converting images to webp format. Webp seems to be the future for image formats. It provides a small file size and retains a majority of the content. It helps us show the same content we love to put on the internet without having to worry about the page speed being affected too much.
If you do not have the tools install already please visit Google's Webp to get the webp convert and visit NodeJS for the backend framework. If you want to see if you have either of them installed already, open up your terminal and type:
node -- version && cwebp -version
You should receive two separate versions on two lines. If you do not have them installed click the link above. Once those are both installed you are ready to go!
For this project to work we need to get some classes from Node's backend libraries. These libraries allow us to interact with the file system, pathing, and executing terminal commands.
const path = require('path');
const fs = require('fs');
const { exec } = require('child_process');
Path will let us work with directory pathing, fs (short for filesystem) will let us interact with the filesystem, and the exec we are extracting from child_process will let us run terminal commands.
All of these classes are unique to NodeJS and will not work on any frontend framework. The frontend JavaScript libraries do not have access to libraries to interact with the operating system. If you try to run this code in your console of your web browser it will fail.
I will have two constants that are used to say where the files are going to be located and what kind of photo extensions I am looking for.
const desktopPath = '/Users/user/Desktop';
const photoExtensions = ['.jpg', '.jpeg', '.tif', '.tiff', '.png'];
The tool we are using from Google to convert images over has certain restrictions. It cannot convert animated formats such as GIF. If you want to convert those you have to use another tool that Google provides in those documents.
Now understand with how this is setup that it will use a static path. I am having it search the desktop for all the files I want to be converted. You can change this to how you want it to work. We will now create two functions that look over the files and pick out the photos.
const isPhoto = fName => {
let result = false;
photoExtensions.forEach(ext => {
if(ext === path.extname(fName)) result = true;
});
return result;
}
const files = fs.readdirSync(desktopPath).map(fileName => {
return fileName;
})
.filter(isPhoto);
The bottom function will get all files and directories, the second function will get all the files that end in the format we want them to. The Map function takes a return value from a function and modifies their value. The filter value will only retain the items from the array that meet the criteria. It is the power that JavaScript has with array values.
These functions are amazing to use and are built into the core functionality of JavaScript. It is not unique to NodeJS and you should become familiar with all array functions that JavaScript has to manipulate and extract data.
The last set of logic we will use is running a terminal command to convert the data. We are going to replace the \s (space)s with an escape character to ensure any file names that have spaces in them are accounted for.
Terminal commands are not a fan of spaces because they use them to separate logic. We have to add the escape so the terminal understands that they are a part of the file name and not separate commands.
files.forEach(file => {
file = file.replace(/(s+)/g, '\$1');
exec(
"cwebp -q 20 " + " -o "
+ path.join(desktopPath, file)
+ ".webp "
+ path.join(desktopPath, file),
(error, stdout, stderr) => {
if(error) {
console.log(`error: ${error}`);
return;
}
if(stderr) {
console.log(`stderr: ${stderr}`);
return;
}
console.log(`stdout: ${stdout}`);
});
});
The exec will handle the execution of Google's cwebp tool to generate the files. We are using to flags here to give it some instruction.
The callback function allows use to display the feedback from the terminal to the NodeJS console. This is a standard format of how the information is received back. Additional logic can be added here (such as additional functions) if required.
const path = require('path');
const fs = require('fs');
const { exec } = require('child_process');
const desktopPath = '/Users/user/Desktop';
const photoExtensions = ['.jpg', '.jpeg', '.tif', '.tiff', '.png'];
const isPhoto = fName => {
let result = false;
photoExtensions.forEach(ext => {
if(ext === path.extname(fName)) result = true;
});
return result;
}
const files = fs.readdirSync(desktopPath).map(fileName => {
return fileName;
})
.filter(isPhoto);
files.forEach(file => {
file = file.replace(/(s+)/g, '\$1');
exec(
"cwebp -q 20 " + " -o "
+ path.join(desktopPath, file)
+ ".webp "
+ path.join(desktopPath, file),
(error, stdout, stderr) => {
if(error) {
console.log(`error: ${error}`);
return;
}
if(stderr) {
console.log(`stderr: ${stderr}`);
return;
}
console.log(`stdout: ${stdout}`);
});
});
Put some images into the folder you added to your constant and run the Node program. You should see all of your files with their new .webp counter parts sitting next to each other.
I chose one of my files so you can see above it changed from 86kb to 12kb. That is quite a size difference! If your website has dozens of photos on it think of the change this could give you. The way I have the cwebp script setup they will retain the same dimensions. So if you need to change over a lot of images they will retain the same shape so you can 1-1 replace them.
This type of scripting can help take the hard work out of creating batch work. Instead of manually fixing all your documents let the computer help you and take care of the basic work. Go onto other articles I have written to help you in your future!
Create a simple terminal application that can let you know how much weight you need to put on the ba...
Relying on HTML to validate your forms is just one step in ensuring visitors enter their information...
NodeJS can help you automate simple tasks. Being a web developer you can achieve the same goals as o...
Python can take boring tasks away from you so you can continue to do other things. It is a scripting...
Most WordPress sites use Apache as their server. Apache has a lot of tools built into it to speed up...
@goodeveningtech
@cobb208
@cobb208_cobb
@goodeveningtech
@corycobb208