All About NPM Packages
Every Node.js project starts with a package.json
file.
In the previous part of the Node.js Simplified Tutorial series, you learned about exporting and requiring Node.js modules. Here, I'll talk about npm, an indispensable tool in your Node.js experience.
Node's package manager, suggestively named npm, is a very powerful tool used to share your code as packages. Not only that, but it allows you to reuse code written by other developers inside your own package, as dependencies. Each package is identified using a package.json
file.
The package.json
file is used for specifying important details about your project such as its name, description, version, entry file, production dependencies, and development dependencies. You can even define command line scripts to be run through npm, slowly eliminating the need for task runners.
Creating a npm package
Creating your first package is as simple as writing a single command line. Open up your terminal, go to your project's root folder and run the following command:
npm init
This is going to ask you to provide basic details about your npm package. The name
and description
you provide here are the ones that will be used when publishing the package to npm. Don't worry about the entry point
for now: the default is index.js
and you'll see why that is in the following section.
name: (project) my-project
version: (1.0.0) 1.0.0
description: This is a sample project for the Node.js Simplified Tutorial.
entry point: (index.js) index.js
test command:
git repository: https://github.com/alexgrozav
keywords: nodejs
author: Alex Grozav
license: (ISC) ISC
After you're done , the command will generate a file called package.json
that will contain all the details you provided. This will be the configuration of your npm package.
Your package.json
file should look like this:
{
"name": "my-project",
"version": "1.0.0",
"description": "This is a sample project for the Node.js Simplified Tutorial",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "https://github.com/alexgrozav"
},
"keywords": [
"nodejs"
],
"author": "Alex Grozav",
"license": "ISC"
}
The package.json
file does a lot more than provide basic package details. It's the place where you specify the development and production dependencies that your package has, but we'll get back to that later in this article.
For now, it's easiest to think of every Node.js project as a package and to think of every package as a module.
Requiring a npm package
In my previous tutorial you've learned how Node.js handles require statements for relative paths. You can also require npm packages in the same way.
It's important to understand that when you require a package you will actually require the file specified in the main
field of your package.json
file. This is same as the entry point
you specified during the npm init
step.
const myPackage = require('package-name');
After path resolving, Node.js will require the file specified in the main
field of the package-name/package.json
file or, if the main
field isn't specified, it will look for an index.js
file:
const myPackage = require('package-name/index.js');
Adding package dependencies
Undoubtedly, the best thing about creating your own npm package is that you can specify, install and then use other developer's packages. This saves up a lot of time, with the npm registry offering more than 600,000 packages for you to use.
When I was learning Node.js, I didn't understand the difference between production and development dependencies very clearly. Here's what is different:
Installing dependencies for production
Production dependencies are the ones that your package actually depends on. These dependencies will need to be installed alongside your own package in order for it to run. Don't worry though, npm handles the dependencies for you.
What this basically means is that, when someone else installs your package, the production dependencies you specify will be automatically installed together with it.
npm install --save lodash
Note: You can use the -S
shorthand instead of --save
.
Installing dependencies for development
Specifying development dependencies is perfect for installing packages that help you get to the final version of your package, but do not directly affect the functionality of your package.
Development dependencies usually provide you with capabilities such as testing, compiling, bundling, and other things needed during development only.
npm install --save-dev gulp
Note: You can use the -D
shorthand instead of --save-dev
.
Installing packages globally
Global packages are made available system-wide. You should only install packages globally if they offer a command line executable or if their documentation suggests you to do so.
Typically, you will need install test runners, testing frameworks, task runners, languages, and bundlers globally.
npm install --global gulp-cli
Note: You can use the -g
shorthand instead of --global
.
The node_modules
folder
Every time you install a local dependency, npm downloads and installs the package and its dependencies inside a folder called node_modules
, where you can find and explore all of your package's dependencies.
After each saved installation, your production or development dependencies will be listed inside the package.json
file under dependencies
and devDependencies
, respectively:
{
...
"dependencies": {
"lodash": "^4.17.5"
},
"devDependencies": {
"gulp": "^3.9.1"
}
}
If you want to install all the dependencies of an existing package, simply run the install command without any argument:
npm install
Publishing your package to npm
When you're ready to share your package with the world (if you want to, of course), you can publish your package to the public npm repository.
- First, make sure you're logged into npm using the login command. This will ask you for your npm username, password, and email.
npm login
- Next, make sure you have specified a unique name, valid repository url, and semantic version in your
package.json
. Publish your package by running the publish command:
npm publish
- Now your package is available for installation to other developers using the name you've specified.
npm install --save your-package-name
Lately, good npm package names have been pretty scarce, like domains, because everyone is trying to reserve a nice name for themselves.
What's next?
Now you're ready to create packages, install dependencies and perhaps, even give something back to the open source world someday.
In my Power of NPM Scripts article, I've written about the now-popular npm scripts and how they work. They're a great addition to your workflow, and you won't need to rely on a task runner such as gulp or grunt anymore.