vsanse/iMinify

View on GitHub
iminify.js

Summary

Maintainability
A
1 hr
Test Coverage
#!/usr/bin/env node
const fs = require("fs"),
      path = require("path"),
      yargs = require('yargs'),
      chalk = require("chalk"),
      figlet = require("figlet"),
      clear = require("clear"),
      confirm = require('prompt-confirm'),
      imgEngines   = require('./engine'), 
      CURR_DIR = process.cwd(),
      engines  = new imgEngines(CURR_DIR);
      
clear();
console.log(
    chalk.bold.yellow(
        figlet.textSync("iMinify", { horizontalLayout: "full" })
    )
);

const argv = yargs
    .scriptName('minify')
    .usage('Usage: $0 [options]')
    .option('quality', {
        alias: 'q',
        description: 'Define quality of images[1-100](Default:100)',
        type: 'number'
    })
    .option('alphaQuality', {
        alias: 'aq',
        description: 'Define alphaQuality of PNG images. Required for webp Conversion[1-100](Default:100)',
        type: 'number'
    })
    .option('progressive', {
        alias: 'p',
        description: 'If want progressive Jpeg (Default:false)',
        type: 'boolean'
    })
    .option('speed', {
        alias: 's',
        description: 'Handles dithering and compression level(png)[1-11](Default:1)',
        type: 'number'
    })
    .option('optimizeLevel', {
        alias: 'ol',
        description: 'Select an optimization level between 1 and 3[gif].The optimization level determines how much optimization is done; higher levels take longer, but may have better results.(Default:2)',
        type: 'number'
    })
    .option('interlaced', {
        alias: 'il',
        description: 'Interlace gif for progressive rendering[gif].(Default:true)',
        type: 'boolean'
    })
    .option('outputDir', {
        alias: 'o',
        description: 'Define output folder name(Default: replace files with optimized ones at same location)',
        type: 'string'
    })
    .option('inputDir', {
        alias: 'i',
        description: 'Define images folder name(Default: traverse all sub-directories in current directory)',
        type: 'string'
    })
    .option('webp',{
        alias: 'w',
        description: 'create webp image from your PNG/JPG image. Default: false',
        type: 'boolean'
    })
    .option('minify',{
        alias: 'm',
        description: "Make this false if you don't want image optimization.e.g- create only webp images without minification: Default: true",
        type: 'boolean'
    })
    .option('lossless',{
        alias: 'l',
        description: "Make this true if you want lossless compress instead of lossy. In case of lossless no need to define quality parameter. Default: false",
        type: 'boolean'
    })
    .help()
    .alias('help', 'h')
    .argv;

const outputDir = argv.outputDir,
      inputDir = argv.inputDir,
      inputPath = inputDir?path.join(CURR_DIR, inputDir): CURR_DIR,
      quality  = argv.quality?argv.quality:75,
      progressive = (typeof(argv.progressive)==="undefined" || argv.progressive === true) ?true:false,
      speed = argv.speed?argv.speed:1,
      optimizeLevel = argv.optimizeLevel?argv.optimizeLevel:2,
      interlaced = (typeof(argv.interlaced)==="undefined" || argv.interlaced === true) ?true:false,
      lossless = argv.lossless?argv.lossless:false,
      webp = argv.webp?argv.webp:false,
      minify =(typeof(argv.minify)==="undefined" || argv.minify === true) ?true:false,
      alphaQuality = argv.alphaQuality?argv.alphaQuality:75;

function walk(dir, outputPath){
    const filesToWalk = fs.readdirSync(dir);
    // Run optimization engines on directory
    if(minify){
        engines.optimizejpg(dir, outputPath, quality, progressive, lossless);
        engines.optimizepng(dir, outputPath, quality, speed, lossless);
        engines.optimizegif(dir, outputPath, interlaced, optimizeLevel);
        engines.optimizesvg(dir,outputPath);
    }
    if(webp){
        engines.createwebp(dir, outputPath, quality, alphaQuality);  
    }
    // get next directory
    filesToWalk.forEach(file => {
        const origFilePath = path.join(dir, file);
        // get stats about the current file
        const stats = fs.statSync(origFilePath);
        if (stats.isDirectory()) {
            if(outputDir){
                let filePath = path.join(dir, file).split(inputPath)[1];
                outputPath = path.join(CURR_DIR, outputDir, filePath);
            }
            else{
                outputPath = path.join(dir, file);
            }
            // recursive call
            walk(
                path.join(dir, file),
                outputPath
            );
        }
    });
}

function start(){
    if(inputDir){
        walk(
            inputPath,
            outputDir?path.join(CURR_DIR, outputDir,inputDir):path.join(CURR_DIR, inputDir)
        );
    }
    else{
        walk(
            inputPath,
            outputDir?path.join(CURR_DIR, outputDir):CURR_DIR
        );
    }
}

if(!outputDir){
    console.log(chalk.bold.red("This will replace current images with minified/optimized images."));
    const prompt = new confirm(chalk.red("Continue?"));
    prompt.originalDefault = false;
    prompt.run()
    .then(function(answer) {
        if(answer){
            start();
        }
        else{
            yargs.showHelp();
        }
    }); 
}
else{
    start();
}