Blog

01
June 2015

Gavin Pickin

Cordova Hooks - Deep Drive into my Cordova Cleanup Hook - written in NodeJS

Android, cfObjective, Conferences, Cordova / Phonegap, Dev.Objective, Ionic, Javascript, Mobile Development, Node.js

After my session about Dev.Objective() called “Getting your Hooks into Cordova - Workflows and Build Helpers”, I decided I should do a deep dive into each of my Hooks I discussed in my presentation, and today we’ll look at my Cordova Cleanup Hook, written in NodeJS.

My presentation mini site is available here on my blog at http://www.gpickin.com/devobj2015/cordovahooks/

As I add more blog posts about this topic, I will continue to update the mini site.
The minisite has links to the gists of all the hooks I had, the slides and links to the few blog posts I did find on the topic.

For more information on what hooks are, please refer to my Session Review and Overview here: Post Conference - Session Review - Getting your hooks into Cordova- Workflows and Build Helpers

The next hook in my hybrid mobile workflow with Cordova, is my Cordova Cleanup hook.

This hook is setup to run in the BEFORE_BUILD.
This hook is written with NodeJS, so it will work on MacOSX and Windows, and this hook is useful with iOS, Android, Windows, any Hybrid Mobile Platform. 

This script is based upon one originally posted on Nic Raboy’s Blog called “Hooks With Apache Cordova Mobile Applications
I modified this hook to make it behave slightly differently, which I will explain as we walk through the code.

This is a simple script that cleans up those annoying operating system files like .DS_Store and Thumbs.db etc. It could be configured to clean up more files by adding to a simple switch statement.
Lets dive into the code.

The hook is found online as a github gist: https://gist.github.com/gpickin/218068bf525a8f02d2a0

 

#!/usr/bin/env node

First line, we need to learn the Cordova CLI build system know how to interpret this hook. This line shows it is a Node script. Remember to make the script executable, otherwise your hook will not be run.

 

// Original : https://blog.nraboy.com/2015/01/hooks-apache-cordova-mobile-applications/
// Modified by Gavin Pickin - 05/09/15

Next we have a comment, showing where I got the original code, and when I last modified this script. 

 

var foldersToProcess = [
    "js",
    "css"
];

Here we have an array of folders we wish to search for the files we wish to clean up. Originally this script was written to only check those directories, but I made a simple change, to recursively search through subfolders as well. We will see how that works later in the file.
To use this hook, you do not need to edit anything below this point, unless you are adding more FILE types to search for.

 

console.log('-----------------------------------------');
console.log('Cordova Cleanup Starting');

Next we output to the console so when debugging the build, we can see when this hook starts processing.

 

foldersToProcess.forEach(function(folder) {
    processFiles("www/" + folder);
});

Now we want to loop over each element in the foldersToProcess array, calling a function for each element, prcoessFiles, passing in the path we want to process the files for.

 

function processFiles(dir) {
    ...
}

The rest of the file is a big function, the meat of the file… processFiles function.

 

fs.readdir(dir, function(err, list) {
    …
}

First we read the directory passed into the function… using fs.readdir, passing in a function which is called with Node’s convention, err and data… in this case, the list of files.

 

if(err) {
    console.log('processFiles err: ' + err);
    return;
}

Again, a Node convention, check for an Error, if you find one, perform an early exit, otherwise, continue through the function.

 

list.forEach(function(file) {
    ...
}

Next we loop through each element of the file list from the directory. 

 

file = dir + '/' + file;
fs.stat(file, function(err, stat) {
    ...
}

Next, we save the full path to the file in a var ‘file’ and then pass that into fs.stat().
fs.stat() returns a Stat object with information of the file system object. More information can be read on that here. https://nodejs.org/api/fs.html#fs_class_fs_stats

 

if(!stat.isDirectory()) {
    …
}
else {
    processFiles( file );
} 

Next, we check if the element in the directory we’re looping over is not a directory. If it is a directory, we recursively call processFiles(). This is one of the additions I made. If this element is not a directory, then we enter the IF statement (shown below).
 

switch(path.basename(file)) {
    case ".DS_Store":
        fs.unlink(file, function(error) {
            console.log("Removed file " + file);
        });
    break;
    case "Thumbs.db":
        fs.unlink(file, function(error) {
            console.log("Removed file " + file);
        });
    break;
    default:
        //console.log("Skipping file " + file);
    break;
}

Here is the switch that does the work. The expression is path.basename(file) which gets the file name (separated from the path)… and if it matches one of the cases, it removes the file from the system. This could be made to perform any action you require on a file to file basis. Switch statements are fast, so that is simple way to solve this problem, but you could alter this to use regex, or something similar.

That’s that. Simple script, but nice little addition to the work flow. 

During the presentation, we had a pretty open conversation, and we discussed other uses of a script like this. We thought maybe you might keep your PSD files in your images folder, alongside the jpg and png files, for simplicity, and sharing, but you obviously don’t want to deploy hundreds of mb of PSD files. Maybe a hook like this would be helpful in this case?

This runs before build so this happens in the source folder, so when you delete the files, it removes the files from the source www folder, before the build process moves the files to the relevant platform folders. So if you delete psd files it will delete the PSD files from the source www folder.
If you set the hook file in a after_build, you can target the platforms www folder and clean up the PSD files after the fact, and leave the PSDs in the source www. This is exactly how the Uglify hook works (that we will look at in another blog post), it does not minify and uglify anything from the source files, only the files in the platform folders.

The hook is found online as a github gist: https://gist.github.com/gpickin/218068bf525a8f02d2a0

Any ideas on other uses for a hook like this? Let me know.
Have a good one.

Blog Search