[et_pb_section bb_built=”1″ fullwidth=”on” specialty=”off” _builder_version=”3.0.64″ next_background_color=”#000000″][et_pb_fullwidth_post_title admin_label=”Blog Post Header” _builder_version=”3.17.2″ title=”off” meta=”off” categories=”off” comments=”off” featured_placement=”background” text_orientation=”center” module_class=”blog_post_header” title_font_size=”60px” background_blend=”saturation” title_font=”Raleway|on|||” title_text_color=”#274060″ title_letter_spacing=”2px” meta_font=”Raleway||||” meta_font_size=”20″ meta_text_color=”#274060″ meta_letter_spacing=”2px” background_position=”bottom_center” /][/et_pb_section][et_pb_section bb_built=”1″ _builder_version=”3.0.63″ prev_background_color=”#000000″][et_pb_row _builder_version=”3.0.63″][et_pb_column type=”4_4″][et_pb_text admin_label=”Blog Post” _builder_version=”3.17.2″ border_style=”solid” module_alignment=”left” text_font=”||||” header_font=”||||” max_width_tablet=”50px”]

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.

Package managers aren’t a new concept but I do believe they’re getting incrementally better. Such is the case with the Node.js Package Manager, npm for short, though sometimes it’s also referred to as Node.js Packaged Module. The npm tool makes it easy for JavaScript developers to share, reuse and maintain code. The primary site for npm is npmjs.com. Here you’ll find a vast repository, like a store, where many thousands of Node.js packages reside. The best part is it’s free to the community—one of the reasons Node.js has taken off so well, in my opinion. Let’s dive in and learn more about how npm works on IBM i.

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

For the sake of this article, let’s say we want to download and use the jshint tool so we can ensure our JavaScript source is valid (i.e., it can check for syntax errors, which is very relevant considering JavaScript doesn’t have a compiler).

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
jshint@2.5.11 node_modules/jshint
├── strip-json-comments@1.0.2
├── underscore@1.6.0
├── exit@0.1.2
├── console-browserify@1.1.0 (date-now@0.1.4)
├── minimatch@1.0.0 (sigmund@1.0.0, lru-cache@2.5.0)
├── shelljs@0.3.0
├── cli@0.6.5 (glob@3.2.11)
└── htmlparser2@3.8.2 (domelementtype@1.1.3, domutils@1.5.0, entities@1.0.0, domhandler@2.3.0, readable-stream@1.1.13)

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 jshint directory.

$ 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

This 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 file with invalid JavaScript (notice how there isn’t anything on the right side of the equal sign other than the ending semicolon).

---test.js content---
var foo = ;

To run 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 test.js source file. It’s worth noting that the jshint Node.js package was pure JavaScript and didn’t have “native” Node.js module dependencies. If one of the packages npm tries to install is a native node module and requires compiling of C++ code, npm will use an additional tool named node-gyp for that task. The node-gyp tool requires Python and that currently isn’t shipped with IBM i, though I have successfully used the Python port available on perzl.org.

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.

[/et_pb_text][/et_pb_column][/et_pb_row][et_pb_row][et_pb_column type=”4_4″][et_pb_text admin_label=”Contact Form Title” _builder_version=”3.17.2″ background_layout=”dark” text_font=”Raleway|on|||” text_text_color=”#f45d01″ text_font_size=”26″ text_letter_spacing=”2px” module_alignment=”left”]

Need assistance with Node.js?

We can help. Contact us.

[/et_pb_text][/et_pb_column][/et_pb_row][/et_pb_section]

One Response

Leave a Reply

Your email address will not be published. Required fields are marked *