Jhornan Colina
Sep 11 · 6 min read

Then of a week, I finished my first command-line ‘Parcel app’ and I chose to create a post talking about it, I passed a completely week studying and teaching myself how to create a command-line because this was something new for me. When I started studying React, to create a command-line similar to create-react-app was an idea on my head for a long time, so today I will teach you how to create a simple command line.

I like to see this post as Pluton planet when we are building a command-line we need to know how to make it small and beautiful. You should saw some command-lines that have messages with amazing colors and an intuitive interface to the user an example could be Netlify, this is a big reason because I don’t use anymore “Github Pages” to deploy my applications. Before to start we need to know some basic concepts about command-line since if we want to build a little interface as a command-line first we need to know what command-line means.

Command-line (CLI)

“Interface of command line” is a method that allows the user to give instruction to some informatic program thought a line of text, there are a different between CLI and Shell as Shell is an informatics program and CLI is a method. A big example about what is a command-line could be create-react-app and Netlify, when you write create-react-app gonna execute something, that is the task of a command-line in the case of create-react-app will create a folder with some files.

  • Okay, so right now we know that a command-line isn’t an informatics program is a method.
  • Command-line gives instruction to an informatic program with line text.
  • With a command-line, you can execute a file or a program.

Let’s started!

First, we will need some packages because we don’t want to build everything manually, some people passed months or week building these packages and we don’t have time right now.

  • esm: we need to use import, so esm will configure everything for us.
  • figlet: generate banners text with some typographic.
  • listr: some command-line has a task list where you can watch the progress of something like an installation of a package.
  • ncp: we will need to copy and paste some files, so ncp will charge of it.
  • util: we use the promisify.

- npm init
- npm i esm figlet listr ncp

Package Configuration

We need to do some configuration as puts the bin and say to the package if the project will be public or no and the default folders:

Don’t worry, I will treat to explain to you what is happens inside of the package, how you see we have the same dependencies that I gave you, the only differences inside the file are:

  • bin: With bin, we’re saying to the package that we will write some commands to execute some files. Some people write cli.js (the file where we gonna write our command properties) initially.
  • publish config: This helps us ensure that the given package is not tagged with “latest”, published to the global public registry or that a scoped module is private by default.
  • files: The optional files field is an array of file patterns that describes the entries to be included when your package is installed as a dependency.

Project Tree

We need to create some files and folders but don’t worry I will leave you my project tree:

├─bin
├── command-line
├─src
├── cli.js
├─templates
├── template.txt
├─ .gitignore
├─ packpage.json
├─ package-lock

Writing instructions

Okay, we need to write the CLI function and export it, because later of this we gonna do a require inside of “command-line” (Don’t worry I will explain step by step):

  • Write the cli function inside of the cli.js. This function receives argv that will have the text that the user wrote, in this case, will be the name of the folder that we will create.
  • So, at this part, we are importing the cli function from cli.js and passing it
    “process.argv” like a parameter.
  • #!/usr/bin/env node: is an instance of a shebang line: the very first line in an executable plain-text file on Unix-like platforms that tells the system what interpreter to pass that file to for execution. More information.

First Testing

Okay, we have the necessary code to get something of our command, but before to run it we need to run npm link and later run our command.

I know this command line looks very simple, but we will give it complexity. We need to create a command line that copies the content of a folder and then paste it in a different directory.

Welcome Method

Isn't necessary, but if we want that our command is more pretty it’s good to have a presentation message. This function needs to be written inside of the cli file and we will need to use figlet since this package gives us beautiful banners:

Copy and paste Function

First, we need to import promisify from util because sometimes we need to copy and paste a lot of files, so this will be a way to get all those files without problems:

Explanation of the copyTempalteFiles function:

  • templateDir: This will be the direction where we have the templates.
  • targetDir: The direction where we gonna paste all our template files.
  • clobber: Don’t re-write files.

We will need to import Path because this will give us the direction of our templates.

Task List

First I will give you a short introduction of listr: this is a package to make a task list where the user can watch each state of the command.

Explanation:

  • actualPath: we use import.meta.url that gives us the actual path.
  • templatesDir: We use “path resolve” for this, the first parameter for the resolve method will be the actual path getting its pathname and for the second parameter will be the path of our template folder.
  • TaskList: we need to create an async function because tasks need to be called with await because sometimes this taks can take much time. Inside of the function we will create a const calling a class where we will place our tasks.

Calling functions

We will call our two functions HelloMessage and TaskList. First, we call the HelloMessage method, because this will be the presentation then we pass “argv” as a parameter because with this we can get the name for the folder (The name for the folder that we will create).

Final code:

Running our command 🎊

This is the end of our trail, run the command and watch the magic

Ey, if this was useful for you, give me some claps and follow me on my networks!

Twitter: @ToyoJhornan
Github: https://github.com/karttofer

JavaScript in Plain English

Learn the web's most important programming language.

Jhornan Colina

Written by

Hey!, maybe you already know my name, I’m React Developer and JavaScript evangelist two things, two passions.

JavaScript in Plain English

Learn the web's most important programming language.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade