So you want to Node more about NPM.
Tags: node, npm, javascript, tutorial
Published: 2020-06-13 18:03:33

Let's have some hands on time with Node/NPM by making a simple project using an Animal Crossing API! But, before we get into it, let's answer some common questions.

If you prefer to read and then follow along, a quick code run through (in complete silence) is available [here](https://www.youtube.com/watch?v=Q2ML4gyTeyw).
{% youtube Q2ML4gyTeyw %}

## What is NPM and Why do we need it?

[NPM](https://www.npmjs.com/) (Node Package Manager) is an online software registry where open source developers can share their software for others to install and use (these are called "packages"). NPM also comes with a bunch of cli commands we can use in our terminal (we'll be using these commands throughout this project, for the full juicy list go [here](https://docs.npmjs.com/cli-documentation/cli)).

But, why? Picture this... you're writing code, making something like us right now, but there's a lot to do. Though, why do everything? When we can leverage other peoples magic to make our lives easier, rather than build everything from scratch. These packages have been created and uploaded by others to npm ripe for our usage (we'll be using a couple to save time and effort).

---

## Prerequisites

There are a few things that you're going to need before we dive in and start the glorious process of learning.

* The ability to gloss over grammatical and spelling errors 
* [Internet and a Computer](https://www.youtube.com/watch?v=RH1ekuvSYzE)
* [Visual Studio Code](https://code.visualstudio.com/) or your favourite editor
* [Node & NPM](https://nodejs.org/en/download/)

---

## Creating your project

Firstly, create a directory to house your project (name it whatever). For this example, I am going to create a new directory called "acnh". Very readable.

Go into that folder and type the following:

```bash
npm init
```

This will ask you a bunch of questions and then create a `package.json`. If you don't know answers to certain questions, that's fine. We can modify this file as we see fit later, it's just JSON. Bonus: The output from this commands gives a lot of learning tips!

```
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (acnh) 
version: (1.0.0) 0.0.1
description: A node cli to hit an Animal Crossing API.
entry point: (index.js) 
test command: 
git repository: 
keywords: 
author: Tom Nook
license: (ISC) 
About to write to /Users/nook/projects/acnh/package.json:

{
  "name": "acnh",
  "version": "0.0.1",
  "description": "A node cli to hit an Animal Crossing API.",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Tom Nook",
  "license": "ISC"
}


Is this OK? (yes) yes
```
Sweet! Now we have a Node/Npm project. We should be seeing a `package.json` in our project. If you're wondering what the purpose of this is, the official Node docs, give a great [overview](https://nodejs.org/en/knowledge/getting-started/npm/what-is-the-file-package-json/), here's a snippet:

> All npm packages contain a file, usually in the project root, called package.json - this file holds various metadata relevant to the project. This file is used to give information to npm that allows it to identify the project as well as handle the project's dependencies.

---

## Installing our dependencies

As mentioned before we're gonna piggyback of some other peoples cool work by installing some packages using the command `npm install <package>`. This also takes two optional flags `--save` or `--save-dev`. The former adds the package in a `dependencies`key and the latter adds it to the `devDependencies` key in our `package.json`. What's the difference you say?

> If someone is planning on downloading and using your module in their program, then they probably don't need all the fluff we install to make our development easier. In production only the dependencies will be installed.


Keep an eye on your `package.json` as we install the following our dependencies using the command below:

```bash
npm install --save node-fetch
```

Our `package.json` should now look meatier, and we should also now have a `node_modules` folder with all our packages inside (we'll reference the stuff inside this later). We simply installed `node-fetch` which will be used to grab data from our api.

---

## Writing basic some code!


Next open this project up in your editor and create `index.js`, this will hold our core code. In this file add the following:

```javascript
#!/usr/bin/env node
const fetch = require('node-fetch')

fetch(`http://acnhapi.com/v1/fish/oarfish`)
  .then(response => response.json())
  .then(response => console.log(response['catch-phrase']))
  .catch(err => console.log('Nothing found.'))
```

The `#!/usr/bin/env node` is known as a [shebang](https://bash.cyberciti.biz/guide/Shebang) and hints how to execute this Node script (it's only really needed when we're running scripts in the terminal, which we are). Next, the `require` statement allows us to pull in the `node-fetch` package we installed from `npm` (which is stored in the `node_modules` folder) and assign it to a variable for usage. Next, we use the fetch method to hit our api, parse the json and log it to our console (an example response is [here](http://acnhapi.com/v1/fish/oarfish)).

Now let's run this bad boy, make sure you're in the directory and run the command below to see the quote I hate the most.

```bash
node index.js
```

## Writing bonus code!

Hitting the same endpoint is boring, luckily we can pass parameters to our node script e.g. if I ran `node index.js bug tarantula`. All these values are available in a globally accessible array called `process.argv`. Therefore let's update our script to use this:

```javascript
#!/usr/bin/env node
const fetch = require('node-fetch')
const category = process.argv[2]
const value = process.argv[3]

fetch(`http://acnhapi.com/v1/${category}/${value}`)
  .then(response => response.json())
  .then(response => console.log(response['catch-phrase']))
  .catch(err => console.log('Nothing found.'))
```

Boom! Now our `fetch` request is powered off these variables and our script is a lot more cooler. We're pretty much done with code, below are some example commands based of the [api](http://acnhapi.com/doc)!

```bash
node index.js fish oarfish
node index.js bugs tarantula
node index.js bugs common_butterfly
```

---

## NPM Scripts

`npm` has support for the `scripts` property in `package.json`, we can define reusable scripts here and we can run them in the terminal like so: `npm run <command>`. The `scripts` object can have multiple definitions. Let's add one so we don't have to run `node index.js` every time.

```json
{
  "name": "acnh",
  "version": "0.0.1",
  "description": "A node cli to hit an Animal Crossing API.",
  "main": "index.js",
  "scripts": {
    "acnh": "node index.js"
  },
  ...
}
```

and voila now we can run `npm run acnh` instead of `node index.js`. I'll stick an updated list of the example commands above here:

```bash
npm run acnh fish oarfish
npm run acnh bugs tarantula
npm run acnh bugs common_butterfly
```

---
## Some takeaways

The idea is to not commit the `node modules` folder as the package.json (and [package-lock.json](https://docs.npmjs.com/configuring-npm/package-lock-json.html)) are used to keep track of our dependencies, so whenever we start fresh we can just run `npm install` to get all our packages again.

Whilst node magically resolves `node-fetch` in `require` statement and grabs it from the `node_modules` directory. We can also split our code up and require local files. You can read more about that [here](https://nodejs.org/en/knowledge/getting-started/what-is-require/).

If you want to learn more about making your code available on `npm` yourself. Definitely check out this article (straight to the point):

{% link https://dev.to/pgarciacamou/creating-a-cli-tool-using-nodejs-and-npm-315 %}

---

![](https://memegenerator.net/img/instances/67583201/all-done-dude.jpg)