CLI program from scratch rating not rated
SoftXML
                  Programming Books
                Open Web Directory
           SoftXMLLib | SoftEcartJS
xml products   Home page    contact    site map
Contact Us
Latest Blog Articles:   Latest SEO Articles | RSS Feed
DOM manipulation best practices
JavaScript Module Pattern
How to start developing with the Nextjs
Angular application structure
Write Guest Articles
Articles Archive




Loading...

The Art & Science of JavaScript ($29 Value FREE For a Limited Time)
The Art & Science of JavaScript ($29 Value FREE For a Limited Time)









CLI program from scratch


Let’s make this CLI program from the scratch


4. CLI Program to create a HTML , JS template

  • There are libraries to make CLI tool in npm communities (i.e, yargs, commander, meow)
  • In this example, we are going to use libraries called commander chalk & inquirer to build a CLI program

commander

  • The complete solution for node.js command-line interfaces

chalk

  • Terminal string styling
  • chalk libraries give a color to CLI command instead of plain black & white

inquirer

  • A collection of common interactive command line user interfaces

> First, install npm packages


            // console
            $ npm i commander inquirer chalk
            

>> Check the output


            + chalk@3.0.0
            + inquirer@7.1.0
            + commander@5.0.0
            added 37 packages from 31 contributors and audited 46 packages in 4.058s
            found 0 vulnerabilities
            
  • and node_modules folder installed in your current directory because you install npm libraries

> Second, Create command.js (executable file)

>> Command.js


            #! /usr/bin/env node
            const program = require("commander");
            program
             .version("0.0.1", "-v, --version")
             .usage("[options]");
            
            program
             .command("template <type>")
             .usage("--name <name> --path [path]")
             .description("make a template")
             .alias("tmpl")
             .option("-n --name <name>", "enter filename", "index")
             .option("-n --directory <path>", "make the creation path")
             .action((type, options) => {
               console.log(type, options.name, options.directory);
            });
            
            program
             .command("*", { noHelp: true })
             .action(() => {
               console.log("Cannot find the following command")
             program.help();
            });
            
            program
             .parse(process.argv);
            
  • You get program object from commander package

There are many methods in program object

  • version : sets up program version. Usage using --version or -v
  • usage : tells how to use the command line. Usage using -h or --help
  • option : specifies the additional options. For example, we can get file name — name and directory -- directory options
  • command : sets up command line. program.command('template <type>') or program.command('*') . Currently, you can run the command using either cli template html (<type> is html) or all other command * ( using wildcard )
  • action : defines executable function and method. can get the parameters from the command line (i.e, <type>)
  • parse : method that appends to the end of the program object. It helps parsing command and option from process.argv parameters

>> Package.js

Let’s configure in package.js to run the command.js


            // package.json
            {
            ...
             "bin":
               { "cli": "./command.js"
            },
            ...
            }
            

>> Check the output


            $ npm i -g
            /usr/local/bin/cli -> /usr/local/lib/node_modules/node-cli/command.js
            + node-cli@0.0.1
            updated 1 package in 0.246s
            

>> Console using options -v & -h


            $ cli -v
            0.0.1
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
            
            $cli -h
            Options:
             -v, --versioon                  output the version number
             -h, --help                      display help for command
            
            Commands:
             template|tmpl [options]   make a template
             help [command]                  display help for command
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
            
            $cli template
            error: missing required argument "type"
            
  • <type> is a required field; therefore, cli template results ERROR for missing the required <type> parameter

>> Command.js

  • Add HTML & JS template in command.js
  • User prompt using inquirer
  • coloring the console output , error using chalk


                    #!/usr/bin/env node
                    const program = require("commander");
                    const fs = require("fs");
                    const path = require("path");
                    const inquirer = require("inquirer");
                    const chalk = require("chalk");
                    
                    const htmlTemplate = `<!DOCTYPE html>
                    <html>
                    <head>
                    <meta chart="utf-8" />
                    <title>Template</title>
                    </head>
                    <body>
                    <h1>Hello</h1>
                    <p>CLI</p>
                    </body>
                    </html>`;
                    
                    const routerTemplate = `const express = require("express");
                    const router = express.Router();
                     
                    router.get("/", (req, res, next) => {
                       try {
                         res.send("ok");
                       } catch (error) {
                         console.error(error);
                         next(error);
                       }
                    });
                     
                    module.exports = router;`;
                    
                    const exist = (dir) => {
                      try {
                        fs.accessSync(dir, fs.constants.F_OK | fs.constants.R_OK | fs.constants.W_OK);
                        return true;
                      } catch (e) {
                        return false;
                      }
                    };
                    
                    const mkdirp = (dir) => {
                      const dirname = path
                        .relative(".", path.normalize(dir))
                        .split(path.sep)
                        .filter(p => !!p);
                      dirname.forEach((d, idx) => {
                        const pathBuilder = dirname.slice(0, idx + 1).join(path.sep);
                        if (!exist(pathBuilder)) {
                          fs.mkdirSync(pathBuilder);
                        }
                      });
                    };
                    
                    const makeTemplate = (type, name, directory) => {
                      mkdirp(directory);
                      if (type === "html") {
                        const pathToFile = path.join(directory, `${name}.html`);
                        if (exist(pathToFile)) {
                          console.error(chalk.bold.red("File Exists"));
                        } else {
                          fs.writeFileSync(pathToFile, htmlTemplate);
                          console.log(chalk.green(pathToFile, "Creation Successfully"));
                        }
                      } else if (type === "express-router") {
                        const pathToFile = path.join(directory, `${name}.js`);
                        if (exist(pathToFile)) {
                          console.error(chalk.bold.red("File Exists"));
                        } else {
                          fs.writeFileSync(pathToFile, routerTemplate);
                          console.log(chalk.green(pathToFile, "Creation Successfully"));
                        }
                      } else {
                        console.error(chalk.bold.red("Choose either 1) html or 2) express-router"));
                      }
                    };
                    
                    let triggered = false;
                    program
                      .version("0.0.1", "-v, --version")
                      .usage("[options]");
                    
                    program
                      .command("template <type>")
                      .usage("--name <name> --path [path]")
                      .description("Create Template")
                      .alias("tmpl")
                      .option("-n, --name <name>", "Enter file Name", "index")
                      .option("-d, --directory [path]", "Enter file Path", ".")
                      .action((type, options) => {
                        makeTemplate(type, options.name, options.directory);
                        triggered = true;
                      });
                    
                    program
                      .command("*", { noHelp: true })
                      .action(() => {
                        console.log("Cannot find the command");
                        program.help();
                        triggered = true;
                      });
                    
                    program
                      .parse(process.argv);
                    
                    if (!triggered) {
                      inquirer.prompt([{
                        type: "list",
                        name: "type",
                        message: "Choose the template Types",
                        choices: ["html", "express-router"],
                      }, {
                        type: "input",
                        name: "name",
                        message: "Type File Name",
                        default: "index",
                      }, {
                        type: "input",
                        name: "directory",
                        message: "Type File Directory",
                        default: ".",
                      }, {
                        type: "confirm",
                        name: "confirm",
                        message: "Creation? ",
                      }])
                        .then((answers) => {
                          if (answers.confirm) {
                            makeTemplate(answers.type, answers.name, answers.directory);
                            console.log(chalk.rgb(128, 128, 128)("Terminal Closed"));
                          }
                        });
                    }
        
                

>> Package.json

check package.js to see if dependencies (chalk, commander, inquirer) are installed correctly


                    {
                        "name": "node-cli",
                        "version": "0.0.1",
                        "description": "nodejs cli program",
                        "main": "index.js",
                        "scripts": {
                            "test": "echo \"Error: no test specified\" && exit 1"
                        },
                        "author": "GPLEE",
                        "license": "ISC",
                        "bin": {
                            "cli": "./command.js"
                        },
                        "dependencies": {
                            "chalk": "^2.4.1",
                            "commander": "^2.15.1",
                            "inquirer": "^5.2.0"
                        }    
                    }
                

>> RUN

Simply cli on the terminal


                $ cli
                

> Finally, Our own CLI tool for templating the HTML and JS

Tag cloud

Rate This Article
(votes 2)

No Comments comments

Post Comment

We love comments on this blog - they are as important as anything we write ourself. They add to the knowledge and community that we have here. If you want to comment then you�re more than welcome � whether you feel you are a beginner or an expert � feel free to have you say.



* = required
Leave a Reply
Name *:
Email *
(will not be published):
Website:
Comment *:
Human Intelligence Identification *:
What is the background color of this web page?
  
Close
Please enter a valid email Please enter a valid name Please enter valid email Please enter valid name Enter valid year
™SoftXML.   Privacy Statement  |  Article Archive  |  Popular Web Development Books
^Top