Introduction to NPM

What is NPM?

NPM stands for Node Package Manager, and is the default way to extend your Node applications.

There are an absolute ton of packages available to install and use immediately, making NPM wildly popular for software developers.

What is Node?

Node.js, or often simply just Node, is a Javascript runtime environment that allows Javascript code to be executed outside of the web browser.

It first came about in 2009 when the creator (Ryan Dahl) took Google’s V8 Javascript Engine which powers its Chrome browser, and repurposed it. Adding in additional logic allowing it to be used independently to execute Javascript on the server.

This opened up a whole new world for frontend Javascript developers to start writing code for the backend. Many of these developers are called Full-Stack Javascript Developers now.

How to setup an NPM project

While NPM is a command-line (CLI) tool, it’s registry is available online at npmjs.com.

It’s very easy to search for packages directly from the website, before installing them locally.

In order to illustrate things better, let’s create an NPM Project and play around a bit with the package manager.

If you don’t have npm or node installed, then take a look here for a quick setup. Alternatively, download node here.

First, we need to make sure we have a directory to work in. Let’s create one and move into there.

mkdir -p ~/src/tutorials/npm_testing cd $_
Code language: Bash (bash)

Great, now we will have to run npm init to initiate an NPM project.

$ npm init 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: (npm_testing)
Code language: Bash (bash)

We will now be asked to customise our application, but we’re happy with all the default for now, so just press Enter at each of the prompts for now.

$ npm init 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: (npm_testing) version: (1.0.0) description: entry point: (index.js) test command: git repository: keywords: author: license: (ISC) About to write to /Users/ao/src/tutorials/npm_testing/package.json: { "name": "npm_testing", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" } Is this OK? (yes) yes
Code language: Bash (bash)

If you want to do this quickly next time, you can always just pass the -y flag to npm init and you won’t be prompted for any inputs.

$ npm init -y Wrote to /Users/ao/src/tutorials/npm_testing/package.json: { "name": "npm_testing", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" } ?????????????????????????????????????????????????????????????????? ? ? ? New minor version of npm available! 6.4.1 ? 6.13.7 ? ? Changelog: https://github.com/npm/cli/releases/tag/v6.13.7 ? ? Run npm install -g npm to update! ? ? ? ??????????????????????????????????????????????????????????????????
Code language: Bash (bash)

So what has really been created now?

Let’s take a look in the directory, issue the ls command and you will see a new file called package.json. If we cat this file, we see the following output:

{ "name": "npm_testing", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" }
Code language: JSON / JSON with Comments (json)

We now need a file called index.js as highlighted under the main key. You can change this to anything you like, but these defaults are fine for us at the moment.

Run touch index.js from the CLI to create the new file.

At this stage we opt to open our project directory in a code editor, my chosen one at the moment is Visual Studio Code. There is a command-line alias available that allows me to execute the command code . in the directory I want to open to load the project in vscode.

Now we can start writing some NodeJS code and make use of an NPM module.

Let’s put the following code in our index.js file:

const request = require('request'); request('https://ao.gl', { json: false }, (err, res, body) => { if (err) { return console.log(err); } console.log(body.url); });
Code language: JavaScript (javascript)

If we try to run this from the CLI, we are greeted by some errors:

$ node index.js internal/modules/cjs/loader.js:583 throw err; ^ Error: Cannot find module 'request' at Function.Module._resolveFilename (internal/modules/cjs/loader.js:581:15) at Function.Module._load (internal/modules/cjs/loader.js:507:25) at Module.require (internal/modules/cjs/loader.js:637:17) at require (internal/modules/cjs/helpers.js:22:18) at Object.<anonymous> (/Users/ao/src/tutorials/npm_testing/index.js:1:79) at Module._compile (internal/modules/cjs/loader.js:689:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10) at Module.load (internal/modules/cjs/loader.js:599:32) at tryModuleLoad (internal/modules/cjs/loader.js:538:12) at Function.Module._load (internal/modules/cjs/loader.js:530:3)
Code language: Bash (bash)

This is because we don’t have the request package available for use yet.

It is an easy fix, all we need to do is issue the npm install request command. (npm i request for short)

$ npm i request npm notice created a lockfile as package-lock.json. You should commit this file. npm WARN [email protected] No description npm WARN [email protected] No repository field. + [email protected] added 48 packages from 59 contributors and audited 63 packages in 3.773s found 0 vulnerabilities
Code language: Bash (bash)

Now let’s try and run node index.js once more.

$ node index.js undefined
Code language: Bash (bash)

No errors this time, great! But we get an undefined response. Let’s fix that quickly. Update our code:

const request = require('request'); request('https://ao.gl', { json: false }, (err, res, body) => { if (err) { return console.log(err); } console.log(res.statusCode, body.length); });
Code language: JavaScript (javascript)

And run it again:

$ node index.js 200 129761
Code language: Bash (bash)

We printed out 2 values, firstly the status code of the request, followed by the length of the HTML body we got back.

NPM Modules Directory

NPM stores everything in a local directory called npm_modules.

$ ls -lp total 48 -rw-r--r-- 1 ao staff 189 ... index.js drwxr-xr-x 50 ao staff 1600 ... node_modules/ -rw-r--r-- 1 ao staff 13120 ... package-lock.json -rw-r--r-- 1 ao staff 275 ... package.json
Code language: Bash (bash)

If we take a look in the node_modules directory we will see all the recursive dependencies our project needs.

$ ls -lashp node_modules total 0 0 drwxr-xr-x 50 ao staff 1.6K ... ./ 0 drwxr-xr-x 6 ao staff 192B ... ../ 0 drwxr-xr-x 6 ao staff 192B ... .bin/ 0 drwxr-xr-x 9 ao staff 288B ... ajv/ 0 drwxr-xr-x 6 ao staff 192B ... asn1/ 0 drwxr-xr-x 7 ao staff 224B ... assert-plus/ 0 drwxr-xr-x 12 ao staff 384B ... asynckit/ 0 drwxr-xr-x 6 ao staff 192B ... aws-sign2/ 0 drwxr-xr-x 8 ao staff 256B ... aws4/ 0 drwxr-xr-x 7 ao staff 224B ... bcrypt-pbkdf/ 0 drwxr-xr-x 7 ao staff 224B ... caseless/ 0 drwxr-xr-x 7 ao staff 224B ... combined-stream/ 0 drwxr-xr-x 8 ao staff 256B ... core-util-is/ 0 drwxr-xr-x 8 ao staff 256B ... dashdash/ 0 drwxr-xr-x 8 ao staff 256B ... delayed-stream/ 0 drwxr-xr-x 8 ao staff 256B ... ecc-jsbn/ 0 drwxr-xr-x 12 ao staff 384B ... extend/ 0 drwxr-xr-x 11 ao staff 352B ... extsprintf/ 0 drwxr-xr-x 10 ao staff 320B ... fast-deep-equal/ 0 drwxr-xr-x 13 ao staff 416B ... fast-json-stable-stringify/ 0 drwxr-xr-x 6 ao staff 192B ... forever-agent/ 0 drwxr-xr-x 8 ao staff 256B ... form-data/ 0 drwxr-xr-x 8 ao staff 256B ... getpass/ 0 drwxr-xr-x 6 ao staff 192B ... har-schema/ 0 drwxr-xr-x 6 ao staff 192B ... har-validator/ 0 drwxr-xr-x 10 ao staff 320B ... http-signature/ 0 drwxr-xr-x 7 ao staff 224B ... is-typedarray/ 0 drwxr-xr-x 10 ao staff 320B ... isstream/ 0 drwxr-xr-x 9 ao staff 288B ... jsbn/ 0 drwxr-xr-x 13 ao staff 416B ... json-schema/ 0 drwxr-xr-x 9 ao staff 288B ... json-schema-traverse/ 0 drwxr-xr-x 10 ao staff 320B ... json-stringify-safe/ 0 drwxr-xr-x 8 ao staff 256B ... jsprim/ 0 drwxr-xr-x 8 ao staff 256B ... mime-db/ 0 drwxr-xr-x 7 ao staff 224B ... mime-types/ 0 drwxr-xr-x 6 ao staff 192B ... oauth-sign/ 0 drwxr-xr-x 11 ao staff 352B ... performance-now/ 0 drwxr-xr-x 9 ao staff 288B ... psl/ 0 drwxr-xr-x 7 ao staff 224B ... punycode/ 0 drwxr-xr-x 12 ao staff 384B ... qs/ 0 drwxr-xr-x 9 ao staff 288B ... request/ 0 drwxr-xr-x 7 ao staff 224B ... safe-buffer/ 0 drwxr-xr-x 9 ao staff 288B ... safer-buffer/ 0 drwxr-xr-x 10 ao staff 320B ... sshpk/ 0 drwxr-xr-x 7 ao staff 224B ... tough-cookie/ 0 drwxr-xr-x 6 ao staff 192B ... tunnel-agent/ 0 drwxr-xr-x 14 ao staff 448B ... tweetnacl/ 0 drwxr-xr-x 11 ao staff 352B ... uri-js/ 0 drwxr-xr-x 14 ao staff 448B ... uuid/ 0 drwxr-xr-x 9 ao staff 288B ... verror/
Code language: Bash (bash)

It is very important to never commit this node_modules directory to your SVN, such as Github.

Using git, we can avoid this by adding the directory to the project’s .gitignore file.

echo node_modules >> .gitignore

Closing remarks

NPM is a powerful package manager that gets you up and running quickly.

Writing Javascript Node applications has never been easier, as there are a plethora of community crafted packages available to use for free.

The node_modules directory can really get out of hand and is often massive for larger projects. Never ever commit it to Github and always run a fresh npm i when cloning a Node project locally.

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments