Originally published: IBM Systems Magazine on 4/14/15
I wager to guess that many reading this have their own smartphones and have experienced installing applications from the corresponding app stores (i.e., Apple App Store, Google Play, Amazon Appstore, etc.).
The process is incredibly simple and convenient, which I believe is testament to what can happen when a single company (i.e., Google) owns both ends of the spectrum—the delivery of application and the installation environment.
What if there was a “store” for reusable source code we could use in our applications?
There is such a concept and it’s called a “package manager.” Wikipedia.org gives the following definition to package managers:
A package manager or package management system is a collection of software tools that automates the process of installing, upgrading, configuring, and removing software packages for a computer’s operating system in a consistent manner. It typically maintains a database of software dependencies and version information to prevent software mismatches and missing prerequisites.
NOTE: In the first Node.js article, we discussed how to set up your PASE session environment by running the following two commands so all node and npm binary files resolve correctly.
$ export PATH=/QOpenSys/QIBM/ProdData/Node/bin:$PATH $ export LIBPATH=/QOpenSys/QIBM/ProdData/Node/bin:$LIBPATH
A jshint Example
On the jshint information page, you’ll notice they recommend using the
-g option during installation. This means it will install the package in the global directory.
$ npm install jshint -g
We can learn what the global installation directory is by running the following command:
$ npm config get prefix /QOpenSys/QIBM/ProdData/Node
The global installation directory is located in IBM’s Node installation directory. We don’t want to install our modules into here because they risk the chance of being overwritten when subsequent 5733OPS updates are applied. One of the reasons they recommend installing in the global directory is so commands resolve correctly. In this case, the install process will create a symbolic link for the jshint command to be included in PASE’s
PATH environment variable. We can work around this and I will show how in a bit. First, let’s run the install of jshint without the -g, as shown:
$ npm install jshint firstname.lastname@example.org node_modules/jshint ├── email@example.com ├── firstname.lastname@example.org ├── email@example.com ├── firstname.lastname@example.org (email@example.com) ├── firstname.lastname@example.org (email@example.com, firstname.lastname@example.org) ├── email@example.com ├── firstname.lastname@example.org (email@example.com) └── firstname.lastname@example.org (email@example.com, firstname.lastname@example.org, email@example.com, firstname.lastname@example.org, email@example.com)
Success! When you omit the
-g install option, it will instead place it locally in the current directory—specifically, in the
node_modules directory. List the contents of the current directory and see the
$ ls node_modules/ jshint
If we list the
jshint directory contents, we can see yet another
node_modules directory within it.
$ ls node_modules/jshint/ README.md bin data dist node_modules package.json src
node_modules directory contains all of the dependencies of jshint, which we saw on screen during the initial install. When a Node.js package is installed, it will review the
packages.json file for the dependencies list, and jshint depends on eight other packages: strip-json-comments, underscore, exit, console-browserify, minimatch, shelljs, cli and htmlparser2. When npm realizes a dependency, it will then download that dependency and look to see if it has any dependencies of its own (which in this case htmlparser2 has five dependencies it requires). This is incredibly useful and is one cool reality of what a package manager brings to the table.
$ ls node_modules/jshint/node_modules/ cli exit minimatch strip-json-comments console-browserify htmlparser2 shelljs underscore
Next, we’ll test the jshint functionality by creating the following
---test.js content--- var foo = ;
test.js through the jshint validations, run the following command:
$ jshint test.js -bash: jshint: command not found
It couldn’t find the jshint command because it doesn’t know where to look for it or, better stated, the
node_modules/jshint/bin folder doesn’t exist in our
PATH environment variable. At this point, we have a couple options for invoking jshint. We can alter the
PATH environment variable to have the bin folder, as shown:
$ export PATH=/home/aaron/myproject/node_modules/jshint/bin:$PATH
Or fully qualify the call:
$ node_modules/jshint/bin/jshint test.js test.js: line 1, col 11, Expected an identifier and instead saw ';'. test.js: line 1, col 12, Missing semicolon.
Notice jshint was successfully invoked and conveyed back to the screen that it found an error in our
Easy as an App Store
As you can see, the process of installing Node.js modules and packages is incredibly simple – a lot like an app store. I like that and believe it’s changing the face of open-source development in significant fashion and for the better. In the future, I’ll go through the process of creating your own module and show how to publish it for others to use. One final note: take a look at the many excellent npm resources at this link.
Need assistance with Node.js?
We can help. Contact us.