Command-Line Interfaces or also known as CLIs (build in Node.js), gives developers a chance to automate all mundane tasks, and that too while leveraging the humongous Node.js ecosystem. The credit even goes to the package managers like yarn and npm, which helps CLI gets distributed and be used on different platforms seamlessly.
One of the most prominent reasons to use Node.js to create CLIs is its rich package ecosystem with more than 1.3 million packages in the npm registry. (Source) Just imagine how gigantic is the ecosystem that developers are stepping into with Node.js.
This article is all about why a software developer would want to write a CLI, use Node.js for it, and distribute it without interruption.
There are certain prerequisites to create CLI, so make sure you have them before you begin:
Recommended Read: How To Build CMS Using NodeJS
Here, we will be doing a setup of a basic Node.js project. Follow these steps for the same:
~$mkdir termTranslate
~$cd termTranslate
~$npm init
Once the last step is done, and we have actually created the node project, it is time now to move to make the CLI. What you need to do is right here:
"bin": {
"tran": "./bin/index.js"
}
So, the key, tran that we set in the step above, will act as the keyword for calling the CLI. People will type this keyword in the terminal using the CLI. Besides, you can always choose the name for your choice; however, keeping it simple, short, and semantic is important to type and remember it easily. Also, you can change this name anytime you want.
Know about the Growing Nodejs Development Trends here.
Now, after following all the steps, here is how your package.json file will look like:
{
"name": "termtran",
"version": "1.0.0",
"description": "A CLI to translate between languages in the terminal",
"main": "bin/index.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1"
},
"keywords": [
"cli"
],
"bin": {
"tran": "./bin/index.js"
},
"author": "Your Name",
"license": "ISC"
}
Now, open the index.js file in the bin folder and use the following code in it:
#! /usr/bin/env node
console.log("Hello World!");
In this code, the #! Is known as the shebang line, which specifies the absolute path to the interpreter, which will help run the code.
After that, we will install the CLI and test it as well. For people to call CLI anywhere, we need to install it globally. Navigate to the root directory and then run the following code:
~$npm install -g
The -g flag will signal npm to install it in the system globally, and CLI can be tested by typing a keyword in the terminal.
~$tran
So, if you have been following everything correctly, you will see a message that we console.logged in the index.js file.
We have prepared our CLI, and we will add other functionalities in the same. Also, the basic task for any CLI is to handle the command-line arguments. So, we will receive the language name in our CLI and the sentence that we need to translate. After that, we will parse it.
We will use an npm package ‘yargs’ which is specially made for CLI creation. It will simplify the entire process of parsing the arguments and will help us manage and organize the command line flags.
~$npm i yargs
~$const yargs = require("yargs");
const usage = "\nUsage: tran <lang_name> sentence to be translated";const options = yargs
.usage(usage)
.option("l", {alias:"languages", describe: "List all supported languages.", type: "boolean",
demandOption
: false })
.help(true)
.argv;
In the code given above, we defined an option -I which will print every supported languages when passed by the API. Yargs helps us with --version and --help flags by default.
~$tran lang_name the sentence to be translated
Now, we will need to parse the arguments. So, here’s what we need to do:
const utils = require('./utils.js')
module.exports = { parseSentence: parseSentence };function parseSentence(words) { var sentence = "";
for(var i = 1; i < words.length; i++) {
sentence = sentence + words[i] + " ";
}
Now, call it in index.js
var sentence = utils.parseSentence(yargs.argv._);
Read our other post on Nodejs Advantages.
module.exports = { showHelp: showHelp, parseSentence: parseSentence };const usage = "\nUsage: tran <lang_name
> sentence to be translated";
function showHelp() {
console.log(usage);
console.log('\nOptions:\r')
console.log('\t--version\t ' + 'Show version number.' + '\t\t' + '[boolean]\r')
console.log(' -l, --languages\t' + ' ' + 'List all languages.' + '\t\t' + '[boolean]\r')
console.log('\t--help\t\t ' + 'Show help.' + '\t\t\t' + '[boolean]\n')
}
Now, call it in index.js
if(yargs.argv._[0] == null){
utils.showHelp();
return;
}
module.exports = { showAll: showAll, showHelp: showHelp, parseSentence: parseSentence};
function showAll(){
console.log(chalk.magenta.bold("\nLanguage Name\t\tISO-639-1 Code\n"))
for(let [key, value] of languages) {
console.log(key + "\\t\\t" + value + "\\n")
}
}
let languages = new Map();
languages.set('afrikaans', 'af')
languages.set('albanian', 'sq')
languages.set('amharic', 'am')
languages.set('arabic', 'ar')
languages.set('armenian', 'hy')
languages.set('azerbaijani', 'az')
languages.set('basque', 'eu')
languages.set('belarusian', 'be')
languages.set('bengali', 'bn')
languages.set('bosnian', 'bs')
languages.set('bulgarian', 'bg')
languages.set('catalan', 'ca')
languages.set('cebuano', 'ceb')
languages.set('chinese', 'zh')
languages.set('corsican', 'co')
languages.set('croatian', 'hr')
languages.set('czech', 'cs')
languages.set('danish', 'da')
languages.set('dutch', 'nl')
languages.set('english', 'en')
languages.set('esperanto', 'eo')
languages.set('estonian', 'et')
languages.set('finnish', 'fi')
languages.set('french', 'fr')
languages.set('frisian', 'fy')
languages.set('galician', 'gl')
languages.set('georgian', 'ka')
languages.set('german', 'de')
languages.set('greek', 'el')
languages.set('gujarati', 'gu')
languages.set('haitian creole', 'ht')
languages.set('hausa', 'ha')
languages.set('hawaiian', 'haw') // (iso-639-2)
languages.set('hebrew', 'he') //or iw
languages.set('hindi', 'hi')
languages.set('hmong', 'hmn') //(iso-639-2)
languages.set('hungarian', 'hu')
languages.set('icelandic', 'is')
languages.set('igbo', 'ig')
languages.set('indonesian', 'id')
languages.set('irish', 'ga')
languages.set('italian', 'it')
languages.set('japanese', 'ja')
languages.set('javanese', 'jv')
languages.set('kannada', 'kn')
languages.set('kazakh', 'kk')
languages.set('khmer', 'km')
languages.set('kinyarwanda', 'rw')
languages.set('korean', 'ko')
languages.set('kurdish', 'ku')
languages.set('kyrgyz', 'ky')
languages.set('lao', 'lo')
languages.set('latin', 'la')
languages.set('latvian', 'lv')
languages.set('lithuanian', 'lt')
languages.set('luxembourgish', 'lb')
languages.set('macedonian', 'mk')
languages.set('malagasy', 'mg')
languages.set('malay', 'ms')
languages.set('malayalam', 'ml')
languages.set('maltese', 'mt')
languages.set('maori', 'mi')
languages.set('marathi', 'mr')
languages.set('mongolian', 'mn')
languages.set('burmese', 'my')
languages.set('nepali', 'ne')
languages.set('norwegian', 'no')
languages.set('nyanja', 'ny')
languages.set('odia', 'or')
languages.set('pashto', 'ps')
languages.set('persian', 'fa')
languages.set('polish', 'pl')
languages.set('portuguese', 'pt')
languages.set('punjabi', 'pa')
languages.set('romanian', 'ro')
languages.set('russian', 'ru')
languages.set('samoan', 'sm')
languages.set('scots', 'gd')//gd gaelic
languages.set('serbian', 'sr')
languages.set('sesotho', 'st')
languages.set('shona', 'sn')
languages.set('sindhi', 'sd')
languages.set('sinhalese', 'si')
languages.set('slovak', 'sk')
languages.set('slovenian', 'sl')
languages.set('somali', 'so')
languages.set('spanish', 'es')
languages.set('sundanese', 'su')
languages.set('swahili', 'sw')
languages.set('swedish', 'sv')
languages.set('tagalog', 'tl')
languages.set('tajik', 'tg')
languages.set('tamil', 'ta')
languages.set('tatar', 'tt')
languages.set('telugu', 'te')
languages.set('thai', 'th')
languages.set('turkish', 'tr')
languages.set('turkmen', 'tk')
languages.set('ukrainian', 'uk')
languages.set('urdu', 'ur')
languages.set('uyghur', 'ug')
languages.set('uzbek', 'uz')
languages.set('vietnamese', 'vi')
languages.set('welsh', 'cy')
languages.set('xhosa', 'xh')
languages.set('yiddish', 'yi')
languages.set('yoruba', 'yo')
languages.set('zulu', 'zu')
So, right there, we have created a hash map for all the languages to their code. There are two reasons behind doing that - one it will help in displaying all the languages as and when needed. And, secondly, we must know that API only takes language code into consideration, which means it will display the language even if a wrong language name is entered.
Now we will have to call the showAll() function in your index.js file if the languages flag is true.
if(yargs.argv.l == true || yargs.argv.languages == true){
utils.showAll();
return;
}
module.exports = { parseLanguage: parseLanguage, showAll: showAll, showHelp: showHelp, parseSentence: parseSent
ence };
function parseLanguage (language) {
if(language.length == 2){
return language;
}
if(languages.has(language)){
return languages.get(language)
}
else {
console.error("Language not supported!")
return; //returning null if the language is unsupported.
}
};
After that, we will convert the language to lower case before calling the function in index.js.
if(yargs.argv._[0])
var language = yargs.argv._[0].toLowerCase(); // stores the language.
//parsing the language specified to the ISO-639-1 code.
language = utils.parseLanguage(language);
const translate = require('[@vitalets/google-translate-api](http://twitter.com/vitalets/google-translate-api)')
;if(sentence == ""){
console.error("\nThe entered sentence is like John Cena, I can't see it!\n")
console.log("Enter tran --help to get started.\n")
return;
}translate(sentence, {to: language}).then(res => {console.log("\n" + "\n" + res.text + "\n" + "\n";}).catch
(err => {
console.error(err);
});
We have completed the CLI now. Finally, if you want you can also use chalk and boxen to decorate or enhance the errors and output with colors and boxes.
Hope this guide helped you learn how to create CLI in Node.js. This was a fully portable CLI and you can easily prepare it using these steps mentioned above. So, go ahead and try it yourself now! Happy coding!!
At Your Team In India, we have a pool of certified Node.js engineers. Need help setting up a dedicated team of developers in India? Connect with us our business head now and get a free consultation.