---
layout: post
title:  "Node.js: NPM"
date: 2018-05-15 04:25:33 +0800
author: foo-dogsquared
categories: node-js
tags: [node-js, programming-notes, javascript]
---

Now that we've tackled a little bit about Node, we know that Node.js comes with a huge number of user-created modules that will 
mostly help you solve problems and reduce time tremendously. This gives us a wide area of freedom to how we will structure our 
app and choose our tool into completion. But how do we do this? --- especially if the project becomes larger in scale. 

Of course, you already know the answer from reading the title. NPM!

## What is NPM?
Ah, of course we're starting with this question.

Node Package Manager or *npm* is the default package manager with a command line interface (CLI) that comes with Node. 

If you're not familiar with package managers, a package manager is just a collection of tools that automates installing, removing, 
upgrading and configuring of packages or programs. Think of them like an app store, Windows Store, for example. From that, you can 
navigate around and look for stuff and find a particular program. With one click, the app store will take care the rest for you, 
downloading the app, installing the app, and updating the app. Other examples of package managers are [`apt`](https://en.wikipedia.org/wiki/Advanced_Packaging_Tool) (Debian-based), 
[`DNF`](https://en.wikipedia.org/wiki/DNF_(software)) (Fedora-based), [`pacman`](https://en.wikipedia.org/wiki/Pacman_(Arch_Linux)) (Arch Linux), [`homebrew`](https://brew.sh/) (OS X), and [`chocolatey`](https://chocolatey.org/) (Windows).

There are basically many package managers out there with different purposes, the kinds of package managers that are given as 
examples are for installing programs but for some such as `NuGet` and `npm` are used for handling development libraries and such.

Also, *npm*'s repository holds over *600, 000* packages, one of the (if not, **the**) world's biggest registry for software 
packages... Yeah...

## How do we utilize it?
To get started with *npm*, we need to get into the directory of our project first.

Then, how we start with utilizing *npm* depends on what you want to go.

Let's start with the basics. First, let's run `npm init`.

After that you shall see a bunch of questions that you shall answer. Most of them can be skipped, anyway, but that depends on you.
If you want to create a <code class="fileName">package.json</code> right away, you can run `npm init -y` with the `-y` or `--yes` 
flag that kind of stand for "YES TO ALL OF THEM! NOW GIVE ME THAT JSON!", then you can just edit the information over there if you 
want to.

You'll see the <code class="fileName">package.json</code> and its keys (or fields). Most of them are pretty much self-explanatory. 
The only required fields in there are the `name` and the `version`.
Most likely the ones that are going to get your curiousity is the `main` and `script` keys in the `.json` file. `main` denotes the 
main entry point for your program. Let's say you've published your package and named it `the_dog` and a user installed your 
package. How are they going to use it? With `require()`, of course! Although in this case, it is `require('the_dog')`. On the 
other hand, `scripts` is a field containing a list of aliases that represents a certain command. 

Well, that aside, you can just refer [here](https://docs.npmjs.com/files/package.json), if you want a more concise explanation of 
each field.

If you predict that you are going to create a bunch of <code class="fileName">package.json</code>, you can set some configurations 
to be the default value when you create those initialized `.json` files by `npm set init.<configuration>` in which `configuration` 
stands for the keys that will appear on your <code class="fileName">package.json</code> (although you might have to refer to the 
documentary to search how to reach to that key/field).

For example, when you don't want to edit to get your name and license on each <code class="fileName">package.json</code>, you can 
set your configurations with this:
```bash
    npm set init.author.name "AUTHOR_NAME"
    npm set init.license "MIT"
```

So that each time you set `npm init -y` or similar commands, you'll see that the `author` and the `license` field are already 
filled up with the value you've set with `npm set`.

OK! Now that settled, what's next?

Well, we should probably *install packages* now!

## Installing (and Uninstalling) Packages
The first thing we should about packages is that we can install these either locally or globally.

Local packages are installed through a `node_modules` folder inside of the current directory (of your command line) meanwhile 
global packages are installed in a folder, most likely in the home directory or root directory of your OS or your user's folder. 

Now to find those packages for your specialized needs, you can go the [official webiste of *npm*](http://npmjs.com/) and use their 
package finder for the packages in their repository. You can also find the packages using the command line with:
```bash
    npm search NAME_OF_MODULE
``` 
...which will give a list of the search result complete with relevant information like description, 
the author, its latest version, and the date of update.

### Global Packages
Anyways, first we'll deal with installing packages globally. To install packages globally, you can enter this command:
```bash
    npm install -g NAME_OF_MODULE # or
    npm i -g NAME_OF_MODULE
```

The `-g` flag, as you'd expect, stands for global. You can also install multiple packages in one go by just separating the 
modules with a whitespace:
```bash
    npm install -g NAME_OF_MODULE NAME_OF_MODULE2 NAME_OF_MODULE3
```

Now, there are considerations when you install a package globally. One of them when you want to use that package with the command 
line and another one of them when that package has some features that can be accessed through a command line. Examples of packages 
that are mostly meant to be installed globally (or at least, can be used globally) are `express-generator` (a framework that 
creates a scaffolding for your app), `ember-cli` (similar to `express-generator`), `eslint` (a JavaScript linter), `jshint` (yes, 
another JavaScript linter), and `node-dev` (a very helpful tool that restarts your app every time it is modified).

You can see where your global packages are installed by running this command:
```bash
    npm list -g --depth=0 # or
    npm ls -g --depth=0
```
The `-g` that also obviously stands for global and the thing that'll most likely get your attention, `--depth=0` flag means 
to not list its submodules (or dependencies) 0 level deeper or in other words, none at all. Try to remove or modify the `--depth` 
flag to see what I mean. 

Also, you will see what libraries and their version numbers have you installed globally, so that's a handy command.

Now, what if we don't need that particular package anymore and want to get rid of it? Well, we can just *uninstall* it.
```bash
    npm uninstall -g NAME_OF_MODULE # or
    npm un -g NAME_OF_MODULE
```

Like how you can install multiple packages in one line, you can also uninstall multiple modules in one line:
```bash
    npm uninstall -g NAME_OF_MODULE ANOTHER_MODULE AND_YET_ANOTHER_MODULE
```

### Local Packages
Next, we'll deal with installing packages locally. As previously mentioned, this will not install your packages on a unified 
folder or directory but through the `node_modules` folder inside of your current working directory.

***Well, there are additional details to keep in mind when installing local packages which will be explained by the 
following topics so please do read until the end.***

The installation process is the same except with one teeny tiny difference:
```bash
    npm install NAME_OF_MODULE # or
    npm i NAME_OF_MODULE
```

Yes, keen reader, the `-g` flag is gone. Suprising, isn't it?

Anyways, not only the installation process is mostly the same but also the monitoring process is mostly the same. To look at the 
modules installed in your project, run the same command without the `-g` flag.
```bash
    npm list --depth=0 # or
    npm ls --depth=0
```

If you saw the output from the above command, you'll notice some name with a version number is outputted before the directory 
of the `node_modules`. Well, that came from the <code class="fileName">package.json</code>.

What about uninstalling it? Pfft, mostly the same, too!
```bash
    npm uninstall NAME_OF_MODULE # or
    npm un NAME_OF_MODULE
```

## The <code class="fileName">package.json</code>
The said file, as previously discussed, is created through `npm init`. This particular file is quite an important part when 
it comes into your workflow. How?

Remember how I said that <code class="fileName">package.json</code> serves as a configuration file (in some way)? Well, we can 
put that into practice. You can paste this code, name the file <code class="fileName">package.json</code> and put it in a 
empty directory (or you can just download it <a href="{{ '/assets/dl-files/node-js-npm/package.json' | prepend: site.baseurl }}" download="package.json">here</a> and put it in an empty folder).

```json
{
  "name": "sample-project",
  "version": "1.0.0",
  "description": "This is just a sample exercise.",
  "main": "index.js",
  "dependencies": {
    "lodash": "4.17.10",
    "sass": "1.3.2",
    "test-lib": "2.1.2",
    "underscore": "1.9.0"
  },
  "devDependencies": {
    "node-dev": "3.1.3"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "foo-dogsquared",
  "license": "MIT"
}
```
<p class="caption">package.json</p>

Then once you have the file in place, run `npm install` then wait until it has been resolved. Next, enter `npm ls --depth=0` to 
see the packages installed and you'll see the packages listed in the `dependencies` field in the `.json` file has been installed.
Then, pretend that you're amazed that you have got another trick in your sleeve. Lastly, absorb the knowledge that `npm install` 
basically looks for the dependencies in the <code class="fileName">package.json</code> file if the tool found one on the current 
working directory.

Due to this function, it lets us to be more portable and more accessible. Instead of transferring what could be thousands of small 
files due to the packages and their dependencies, we can just send the <code class="fileName">package.json</code> to 
other developers and be done with it. Well, that is the halfway of the whole picture, anyway.


## Package Maintenance
OK! Now that your app has packages installed, you might wonder if there's any processes you have to worry. And yes there is, 
presumably fellow newb developer! 
There's a lot of them, most of which are not covered in this post, so go check out the 
[official documentation](https://docs.npmjs.com/) of this tool in order to get more out of it.

Anyways, onto the question, what are some of those processes?

I'm pretty sure you have already read the header, maintaining packages!
It is one of the most important processes while developing your app. Basically, you're keeping an eye out for how you install 
your packages and how others would install the needed packages without entirely breaking your project if they try to render it 
on their side of things.

If you want to be secure about maintaining your packages while reducing the problem of breaking your project from a big package 
update, for instance, you can install and lock the version of a package by adding the `--save-prod` or `-P` flag in your standard 
`npm install NAME_OF_MODULE`. 
```bash
    npm install NAME_OF_MODULE -P # saving the package into dependencies
```
Actually, as of *npm 5*, you don't need to worry about that since *npm* does that for you automatically. Still, there are options.

Else if you're using a tool that is mostly for testing and development purposes, you can use:
```bash
    npm install NAME_OF_MODULE -D # saving it into devDependencies
```
Any packages that is installed this way will be saved into the `devDependencies` field which means that packages enlisted in there 
will appear in the development environment and will not appear when pushed into production. 

Else if you want the exact version of a package and lock it in the file:
```bash
    npm install NAME_OF_MODULE -E # saving the package with the exact version number
```

And if you don't want to list packages into <code class="fileName">package.json</code>, you can use:
```bash
    npm install NAME_OF_MODULE --no-save # IDK what's this for but why not?
```

You know what? Just refer [here](https://docs.npmjs.com/cli/install). There a handful of stuff that is not yet mentioned in this 
post.

Oh, and you should keep in mind about how *npm* caches the package whenever you install a new package so that it does not have 
to rely on the internet when it tries to install a package for the second time. If you want to get it clean and declutter from 
the packages that have gathered over time, you can run:

```bash
    npm cache clean
```

You can add a `--force` option in order to... forcefully remove all of the cache stored in wherever *npm* stores its cache (but 
use it if you know what you are doing).

-------

In summary:
* `npm init` first for your app
* `npm install NODE_MODULE` to install *npm* packages
* <code class="fileName">package.json</code> is important and serves as a configuration file for your app (in a way)
* `npm install` to install stuff from a <code class="fileName">package.json</code>
* how to uninstall packages again?
* you can do a bunch of stuff and you can know it by referring to the [official documentation](https://docs.npmjs.com/)
* something about dependencies and how to lock those packages in order to be more reproducible for others

*additions and update of info are upcoming for sure*

Anyway, that is the introduction of *npm*. Far from an ideal *good* introduction and that's the best I could do (for now) but 
hopefully it's enough. Just remember when in doubt, meet Google-*sama* and R.I.P. (~~RIP In Peace~~ Research, Immerse, Practice)
those topics apart! 

## (Re)Sources:
- [A Beginner's Guide to npm --- the Node Package Manager on *SitePoint*](https://www.sitepoint.com/beginners-guide-node-package-manager/)
- [Node.js Introduction Course on *edX*](https://courses.edx.org/courses/course-v1:Microsoft+DEV283x+1T2018/course/)
- [Node.js Notes for Professionals](https://goalkicker.com/NodeJSBook)
- [*npm* Documentation](https://docs.npmjs.com/)
- [*npm* Official Website](http://npmjs.com/) --- also features a search engine for its packages
- [What is the --save option for npm install? on *Stack Overflow*](https://stackoverflow.com/q/19578796/8633667)