Mittwoch, 7. Dezember 2011

Introduction into Node Modules Part I

Lets start with a bit of advertising from Node Package Managers (npm - ww.npmjs.org) own home page:
npm is a package manager for node. You can use it to install and publish your node programs. It manages dependencies and does other cool stuff
There is really nothing I can add to this.

Goal
The goal of this blog post is to show you the simplest way to build your own package.
Therefore I will lead you through the creation of a trivial module which will export 2 functions that capitalize and decapitalize a string - Just toUpperCase and toLoverCase by a more fancy name.

This blog post assumes that you have installed node and npm.

Preparation
First create a new directory named "capitalize" and change into that new directory.

Hector:~ $ mkdir capitalize
Hector:~ $ cd capitalize/

within that directory issue the command "npm init" and follow the "wizard".

Hector:~/capitalize $ npm init
Package name: (capitalize)
Description: capitalizes and decapitalizes a string
Package version: (0.0.0) 0.1.0
Project homepage: (none) www.capitalize.org
Project git repository: (none)
Author name: robert kuzelj
Author email: (none) robert@capitalize.org
Author url: (none)
Main module/entry point: (none) main.js
Test command: (none)
What versions of node does it run on? (~0.6.0)

This will create the following "package.json" file. Which is by far the most important
file when creating and managing node packages.
"npm publish" will use this file when publishing your module locally or to the internet.

Code
Lets start hacking some serious code. First we will create a sub directory called "lib" 
that contains the actual code. We will split our code into 2 files for illustration purposes.

Hector:~/capitalize $ mkdir lib
Hector:~/capitalize $ cd lib
Hector:~/capitalize/lib $ touch capitalize.js
Hector:~/capitalize/lib $ touch decapitalize.js

Now enter this extremely sophisticated code in the file "~/capitalize/lib/capitalize.js"
Now enter the following code in the file "~/capitalize/lib/decapitalize.js"

Finally add the code for the file "~/capitalize/main.js"

Obviously the code within capitalize.js and decapitalize.js could have also been directly in main.js. However I wanted to show you 2 things:

  1. it is good practice to split your module into smaller files and put those files under the lib directory and into lib's child directories.
    You can use a different directory name however the node community has implicitly agreed on "lib" as the default name.
  2. it is good practice to have the entry point of your module require any files in the lib subfolder and reexport those functions that should be accessible from any client code.
Local Publishing
Now lets test our industry strength module before we are going to publish it.
First we will create a symbolic link within the npm system

Hector:~/capitalize/lib $ cd ..
Hector:~/capitalize $ npm link

npm link reads the package.json file and creates a symbolic name using the "name"-entry on top of your OS's symbolic links (at least thats what I assume).

Now lets create some test Javascript that uses our new module. First we create a new directory and create a new npm link within.

Hector:~/capitalize $ cd ..
Hector:~ $ mkdir cap-test
Hector:~ $ cd cap-test
Hector:~/cap-test $ touch test.js
Hector:~/cap-test $ npm link capitalize
capitalize@0.1.0 /opt/local/lib/node_modules/capitalize
./node_modules/capitalize -> /opt/local/lib/node_modules/capitalize

If you execute npm link <module-name> a symbolic OS link that points to the source directory of <module-name> will be created. Any changes within the source directory will be visible within the client directory and can immediatly tested.

Now add the following code to your "~/cap-test/test.js"
This will (hopefully) yield the following output

Hector:package-03 $ node test.js
FOO
bar

Public publishing
We are almost there ;-) only on small final thing. We need to add a user to the registry at www.npmjs.org.

Hector:~ $ npm adduser
Username: robkuz
Password:
Email: robert@capitalize.org

This will create a file named ~/.npmrc that includes your email and your authentication token. This file is  used when you publish anything to the global npm registry.

Now its time to begin our journey into land of the rich and famous. Change back into the root directory of your module and issue npm publish

Hector:~ $ cd capitalize
Hector:~/capitalize $ npm publish

Finally everybody can find our module

Hector:~/cap-test $ npm find capitalize
NAME        DESCRIPTION                                                   AUTHOR   KEYWORDS
capitalize  capitalizes and lowercases strings (example - No Production!) install scripts =robkuz
or install our module by simply issuing the command npm install capitalize.


Parting Words
Please change the "name" key  in the package.json when you following this post.
you can't use "capitalize" as a name on the global npm registry as it is already exclusively assigned to me.

I hope you enjoyed the show.
ps: the next blog will show you how to create command line tools with node.js

Kommentare:

  1. How do you make sure (automatically) that the tests yield the correct results?

    Is there an assert?

    AntwortenLöschen
  2. Hi Gabriel,
    I am bit lost - what "tests" are you referring to?

    AntwortenLöschen
  3. The node community has also implicitly decided on putting tests in a folder called "test" inside the module folder. This way it can be included in the git repository and tests can be added there when others contribute to the project.

    It's also common for the command to run the test to be in package.json under `"scripts" : { "test": "cmd" }`. This way any module can be tested with `npm test`.

    AntwortenLöschen