|

Node Package Manager Tutorial

npm tutorial

This npm tutorial will focus on Node Package Manager, or NPM as it is commonly referred to. NPM serves two main functions. It is a command line tool for running all kinds of development tools and scripts, in addition to a registry of third party libraries. In fact, at the last count NPM has something like 650,000 software packages available! This means for any problem you are trying to solve with Node.js, there is likely a free package already created that you can leverage in your own project. Of course you can find NPM over at https://www.npmjs.com. In addition, if you have an idea for software that you would like to share with the community – you can create your own package and share it with the world. Let’s learn a little more about NPM now.


What is a package.json file?

Before we get moving along, you’ll want to make sure you have npm installed on your system. To check this, you can type something like npm -v at the command line. Your version might be different than what you see here but as long as there is a number value there you are likely good to go.
how to check npm version

While you are at it, it doesn’t hurt to also check the version of node installed. You can do this with node -v at the command line.
how to check the version of node

Now we want to create a new directory named npm-tutorial and then we can move into that directory like we see here.
make directory to hold project

Now we are ready to create a package.json file and learn about how it works. This is a JSON file that holds the basic information about our project. All Node applications are going to have this package.json file. To create your package.json file, go ahead and run npm init.
how to run npm init

When we run the npm-init command, the program walks us through a process to fill out the meta data needed to create the package.json file. We see a package name, version, description, entry point, test command, git repo, keywords, author, license, and a confirmation. Once you go through the process, you’ll have a package.json file which might look something like this.

The main point here is that before you can add any node packages, you must create a package.json file. We took the long route above, but if you’d rather just create the file and accept all the defaults right away – you can type npm init --yes and the file will be whipped up for you in a snap.


How to install a Node module

Well we have our package.json file in place, let’s go ahead and add some third party packages to the project. To start, let’s install the underscore JavaScript library. First off, you can check out the information about underscore at it’s npm page. It shows that to install it, all we need to do is type npm i underscore in our terminal. Let’s do that now.
install underscore with npm

Fantastic. We can check out the package.json file and it has been updated to reflect that the underscore library is now a dependency of our project.

Now in the background, npm did it’s thing and downloaded all the files for the library you installed. We can also see this in the node_modules folder. It now has an underscore folder which holds the files we need to work with underscore js.
packages stored in node_modules

Of note is that within the underscore folder, there is actually another package.json file. In fact, every third party module you install will contain it’s own package.json file – just like your own parent application has a package.json file.


Using an Installed Module

We installed the third party module, let’s now use it. To do so, all we have to do is require it into our project. Create a new index.js file in the root of your project and add this code.

The require function takes the following steps to include a package.

  • Check it it’s a core module, if so load it.
  • Check if a file or folder is being required, if so load it.
  • Check if the named module exists in node_modules, if so load it.

This is how npm resolves a module for you.

So we need to test out underscore to see if it works. In a prior tutorial, we learned about how the every() function in underscore works in the browser. Let’s now port one of those examples over to Node.js. In our index.js file:

We can run the program to see if it works. In this case, underscore will check every person to see if they have a mustache. Not all people have a mustache in this example so it should display false. Let’s see.
underscore in nodejs

Looks like it is working good! This verifies that the library is in fact a part of our project and we can see it is doing it’s job as it should.


Modules can have their own dependencies

When installed a third party module, that package may install it’s own set of dependencies during installation. Let’s see what we mean by that. We can install mongoose for our project by typing npm i mongoose.
npm install mongoose

Inspecting our package.json file shows us the new entry for mongoose as a dependency.

Now, let’s list the contents of node_modules to see what is in there.
mongoose dependencies
Whoa! There are a lot of new folders in there. All we did was install the mongoose package so what happened? Well, it turns out that the mongoose package actually needs a lot of other software packages in order to do it’s job. Therefore, when mongoose is installed, npm automatically installs all of the dependencies of that package. Pretty sweet right? I know you would mess that up if you had to install all those dependencies by hand. I know I would!


NPM Packages and Source Control

If you build out a project to the point where you are going to share it on Github or some other type of source control mechanism, you would never include the node_modules folder. This is because as the application grows, you may see that node_modules folder swell to hundreds of mega bytes of size. If you were to include this in source control, any time another developer wanted to check out your project – they would be waiting on that node_modules folder to download. It’s not a good practice. This is not a problem anyways however, because the package.json file contains all the dependencies the project needs. So if another developer checks out your code, all they have to do is run npm install and npm will download and install any number of dependencies needed right into node_modules on their machine. Here is an example of how to exclude node_modules. First we initialize a git repo.
git init

Then, we add a .gitignore file and specify that we don’t want to include the node_modules folder.
add gitignore file

Now when we run git status again, the node_modules folder is no longer being tracked and committed.
node_modules is now ignored

We can go ahead and add the files and commit them as well.

npm-tutorial $git add .
npm-tutorial $git commit -m "First commit!"
[master (root-commit) f65e415] First commit!

 4 files changed, 193 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 index.js
 create mode 100644 package-lock.json
 create mode 100644 package.json

SemVer (Semantic Versioning)

Let’s look a little closer at the versions of our dependencies from package.json.

  "dependencies": {
    "mongoose": "^5.1.1",
    "underscore": "^1.9.0"
  }

Note that we have mongoose and underscore installed currently. Each of the versions start with a ^ or caret symbol. What does this mean? Well in node packages there are three components. It is in the format of X.Y.Z The X represents the Major version. The Y represents the Minor version. They Z represents the Patch version. This is what is referred to as SemVer or Semantic Versioning. Getting back to that caret character. This indicates that the dependencies should use this Major version. So in our example above, when the dependencies are installed, we want the most up to date version or mongoose as long as it is a part of the 5 Major Version. Similarly, we are interested in underscore which has 1 as the Major Version. In other words, the Major versions must be 5 or 1, however we will take newer minor and patch versions if they are available. This is important! Learn more here.


Listing the Installed Packages

In order to see what the project uses as installed dependencies, we can simply use the list command.
npm list

This lists all of the dependencies in the project, as well as the dependencies of each dependency. Maybe you only want to see what your actual project depends on, and not the entire dependency tree. For this, just use the depth flag set to 0.
npm list depth 0


Viewing Registry Info for a Package

You might want to learn more about the npm package you are using. To do so you could visit the npm website and read up about the package. You could however get a lot of useful information about the package right in the terminal. For example, let’s type npm view mongoose at the terminal.
npm view mongoose

Wow! That is a lot of great information. We can see pretty much everything we need to know about that package. Let’s learn more about underscore too.
npm view underscore


Uninstalling a Package

Of course there will be times when you might want to remove a package from your application. Let’s go ahead and remove underscore from our project.
npm uninstall package

With that, underscore is now removed from our project. If we inspect the package.json file once again, we will see that it is removed from the dependencies area as well. At this point only mongoose is installed as a 3rd party package.


Installing a Specific Version of a Package

There may also be times when a specific version of a library is needed to ensure it works in a given project. Let’s say that our project actually needed the 1.8.3 version of underscore instead of the 1.9.0 version. We can specify which version to install like so.
npm install specific version

Just like that, you have the specific version you need.


Updating an npm Package

It might actually be best if you use the most up to day packages in your project. First, you should check to see if anything is outdated with the npm outdated command. With this, npm can easily determine if any of your packages need to be updated.
npm outdated

Now we can run npm update to update underscore once again.
npm update
Note: running the npm update command will only update the minor and patch versions of anything listed in package.json. Major releases will not be updated. If you need to change the major release you could use npm-check-updates.


What About DevDependencies?

So far we have seen how to make use of dependencies in our project. In other words, our application is going to need these packages to function correctly. There will be times when we only need certain packages during development. This is usually when doing test driven development or some such application. Let’s go ahead and install the Mocha testing package as a development only dependency. We can do so by typing npm i mocha --save-dev at the command line.
npm install dev dependency

This installs mocha for us and if we inspect the package.json file, we can see that we have a new package under the devDependencies section.

This specifies that mocha is to be included when building and testing the application but that it should not be included in a production environment.


npm cheat sheet

Here are a handful of commands to use as a quick reference.

  • npm i <packageName> Install a package
  • npm i <packageName>@<version> Install a specific version of a package
  • npm i <packageName> —save-dev Install a package as a development dependency
  • npm un <packageName> Uninstall a package
  • npm list —depth=0 List installed packages
  • npm outdated View outdated packages
  • npm update Update packages
  • To install/uninstall packages globally, use –g flag.

Node Package Manager Tutorial Summary

In this npm tutorial we learned that every Node application has a package.json file which includes metadata about the project. The name of the application, its version, dependencies, and other information is a part of this metadata. We can make use of NPM to download and install 3rd-party packages from the NPM registry. When we do so, these installed packages and their dependencies will be stored in the node_modules folder. Node packages follow the semantic versioning convention of major.minor.patch.

|