🚄Node On Rails: Bootstrapping the CLI tool
Tags: node, javascript, beginners, webdev
Published: 2020-01-13 16:24:09

Last time we created an essential repo, and today, we will start to implement our first small CLI tool.

### Installing dependencies 
We will need to install the following dependencies.

```bash
yarn add colors commander
```
and the following dev dependencies

```bash
yarn add -D @types/node typescript  ts-node rimraf
```
The dev dependencies are our typical friends if we work with typescript. `@types/node` are the needed type definitions for typescript. `typescript` is, of course, typescript 😏. `ts-node` will it make easy to run typescript directly and at least we have `rimraf` which is a package that can delete folders.

### Setting up the package.json
We now need to define some `npm scripts` to make it easier to run our project.

```
...
"scripts": {
        "dev": "ts-node src/index.ts",
        "build:clean": "rimraf lib",
        "build": "yarn run build:clean && tsc && chmod +x ./lib/index.js",
}
...
```
"dev": This will run our index.ts directly. We don't need to build our project and compile our typescript code to javascript
"build:clean": This will delete our build folder.
"build": Here, we are telling yarn first to clean the build and then to compile the typescript and build our project. The `chmod +x ./lib/index.js` is important. It will make our `index.js` executable so that we can run it as a binary.

We need to add one last thing to our `package.json`, and this is the `bin` key.

```
    "bin": {
        "nor": "./lib/index.js"
    },
```
Now we can run our build version the following way:
```
yarn run nor
```
And also if the user installs this package, he will be able to type
```
nor
```
### Typescript config
```JSON
{
  "compilerOptions": {
    "target": "ES2018",
    "module": "commonjs",
    "sourceMap": true,
    "outDir": "lib/",
    "strict": true,
    "types": [
      "node"
    ],
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "removeComments": true
  },
  "include": [
    "src/**/*"
  ],
}
```
The upper JSON is a basic `tsconfig.json` file. One important key is `outDir`. `outDir` tells the Typescript compiler were to pit the build. "include" tells the Typescript compiler where to look for `.ts` files. It will look into all folders inside the `src/` folder, including the `src` folder. If you want to know more about the `tsconfig.json` write it down below in the comments.

### Our first command
Now that we have our `package.json` ready to go. We can now implement our first CLI command.

Create `src/index.ts`. You can do it like this.
```bash
mkdir src
touch src/index.ts
```
Now open the `index.ts` and add the following line:
```typescript
#!/usr/bin/env node
```
the code above will tell the UNIX system you are running this bin on to use nodejs. It does a little bit more. If you want to read more about it, here is a [Wikipedia link](https://en.wikipedia.org/wiki/Env).

### Importing commander and our first command

```typescript
import program from 'commander'.

program
    .command('hello <name>')
    .description('Prints the given namen')
    .action((name: string) => {
        console.log(`hello ${name})
    })

program.parse(process.argh)
```
To make this one easier to understand. Save the file and type the following command into your terminal
```
yarn run dev hello devto
```
The command should print `hello devto`. Okay, now let us see how it works.

First, we import the `commander` package. Then we will create our `hello` command. `command()` is the part after the binary name or `yarn run dev`. Looking back at our example command, it would be `hello devto`. "hello <name>" is now simple to understand. "hello" is the command, and <name> is a parameter.

The `description()` is the text we will see when we see the help output.

And now the `action()` part. Here happens the actual work. The first argument is a callback, and the first argument of that callback is the first parameter from our command. In our case `<name>`. We are taking that string and just printing it out for now.

`program.parse` awaits some input. We want to give it the argh(arguments) from the terminal.

That's it! We have built our first command CLI tool.

### Building and running our tool
We have already set up our build. We only need to run
```
yarn run build
```
If everything went fine, you should now have a `lib/` folder.
You can run the script directly with
```
node lib/index.js
```
another way is to run
```
yarn run nor
```
If you want to see the help page, you can run
```
yarn run nor -h
//or
yarn run nor --help
```
### Next steps
We will extend this package and start to implement the `new` command. With the `new` command, we want to create a new project.

If this added any value for you, please consider sharing this post on twitter or any other social media. I would be the happiest person on earth.🙏😀

**👋Say Hello!** [Instagram](https://www.instagram.com/lampewebdev/) | [Twitter](https://twitter.com/lampewebdev) | [LinkedIn](https://www.linkedin.com/in/michael-lazarski-25725a87) | [Medium](https://medium.com/@lampewebdevelopment) | [Twitch](https://dev.to/twitch_live_streams/lampewebdev) | [YouTube](https://www.youtube.com/channel/UCYCe4Cnracnq91J0CgoyKAQ)