Updating npm, node.js and express.js globally

There are lots of bubbly install howto's on the web concerning the Node programming environment. But what are the best practices for updating, really?

Updating npm

First of all I tried the obvious:

# npm --version
1.0.6
# npm update -g
npm ERR! TypeError: Cannot call method 'filter' of undefined
npm ERR! at /usr/local/lib/node_modules/npm/lib/utils/load-package-defaults.js:64:15
npm ERR! at cb (/usr/local/lib/node_modules/npm/lib/utils/async-map.js:51:11)
npm ERR! at /usr/local/lib/node_modules/npm/lib/utils/find.js:23:20
npm ERR! at cb (/usr/local/lib/node_modules/npm/lib/utils/graceful-fs.js:31:9)
npm ERR! Report this *entire* log at:
npm ERR! <http://github.com/isaacs/npm/issues>
npm ERR! or email it to:
npm ERR! <npm-@googlegroups.com>
npm ERR!
npm ERR! System Linux 2.6.39.1-linode34
npm ERR! command "node" "/usr/local/bin/npm" "update" "-g"
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! /root/npm-debug.log
npm not ok

"Not ok" indeed. The issue queue for npm shows this is not quirky me, but rather an acknowledged problem, solved since June. "Please curlish to update, and it'll work" is the recommendation. And that is correct. I did:

# curl http://npmjs.org/install.sh | sh
...
It worked
# npm --version
1.0.106

All set.

Updating node

You can probably get away with downloading the source and configuring, making and make installing as if it were a fresh install and everything should be hunky-dory. What I do in the case of node is to keep the source around in an established place, uninstall node, then download the fresh source and install again. The idea also is to leave all the old source trees (or at least the last two or three) so I can go back and install another earlier version if I want to.

Let's suppose we store all our source files in /usr/local/src. It looks like this on my server:

# ls -l
total 25684
drwxr-xr-x 12 couchdb couchdb 4096 2011-05-22 07:53 apache-couchdb-1.0.2
-rw-r--r-- 1 root root 1031474 2011-01-26 14:24 apache-couchdb-1.0.2.tar.gz
drwxrwxr-x 19 root root 20480 2011-05-23 17:06 git-1.7.5.2
-rw-r--r-- 1 root root 2766306 2011-05-20 01:36 git-1.7.5.2.tar.bz2
drwxr-xr-x 11 root root 4096 2011-06-17 09:31 nginx
drwxr-xr-x 12 root root 4096 2011-05-23 17:14 node-git-repo
drwxr-xr-x 11 502 staff 4096 2011-07-29 14:00 node-v0.4.10
-rw-r--r-- 1 root root 12410018 2011-07-20 03:13 node-v0.4.10.tar.gz
drwxr-xr-x 11 502 staff 4096 2011-05-24 11:54 node-v0.4.8
-rw-r--r-- 1 root root 4991396 2011-05-21 03:02 node-v0.4.8.tar.gz
drwxr-xr-x 11 502 staff 4096 2011-07-06 16:46 node-v0.4.9
-rw-r--r-- 1 root root 4994552 2011-06-29 07:29 node-v0.4.9.tar.gz
drwxr-xr-x 7 root root 4096 2011-05-23 19:56 testapp

So since I have node version 0.4.10 installed, I first go into the appropriate directory and uninstall the old version:

# node --version
v0.4.10
# cd /usr/local/src/node-v0.4.10
# make uninstall
# node
-bash: /usr/local/bin/node: No such file or directory

This leaves me free to go to http://nodejs.org/#download and see what the latest stable version is (v0.6.2 at this time of writing), grab it and follow the build instructions:

# cd /usr/local/src
# wget http://nodejs.org/dist/v0.6.2/node-v0.6.2.tar.gz
--2011-11-19 08:53:36-- http://nodejs.org/dist/v0.6.2/node-v0.6.2.tar.gz
Resolving nodejs.org... 8.12.44.238
Connecting to nodejs.org|8.12.44.238|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 9286655 (8.9M) [application/octet-stream]
Saving to: `node-v0.6.2.tar.gz'

100%[======================================>] 9,286,655 9.86M/s in 0.9s

2011-11-19 08:53:37 (9.86 MB/s) - `node-v0.6.2.tar.gz' saved [9286655/9286655]

# tar xvzf node-v0.6.2.tar.gz
# cd node-v0.6.2
# ./configure
# make -j2
# make install
# node --version
v0.6.2

Updating express

# npm update express -g
npm WARN node.io@0.3.6 package.json: bugs['web'] should probably be bugs['url']
npm WARN jsdom@0.2.1 package.json: bugs['web'] should probably be bugs['url']
npm WARN htmlparser@1.7.3 package.json: bugs['web'] should probably be bugs['url']
npm WARN cssom@0.2.0 package.json: bugs['web'] should probably be bugs['url']
npm WARN request@2.0.2 package.json: bugs['web'] should probably be bugs['url']
/usr/local/bin/express -> /usr/local/lib/node_modules/express/bin/express
express@2.5.1 /usr/local/lib/node_modules/express
├── qs@0.3.2
├── mime@1.2.4
├── mkdirp@0.0.7
└── connect@1.8.0
root@crowdclock:~# express --version
2.5.1

To test it out, albeit very superficially, I created a test app and executed it:

$ express testupdate

create : testupdate
create : testupdate/package.json
create : testupdate/app.js
create : testupdate/public
create : testupdate/views
create : testupdate/views/layout.jade
create : testupdate/views/index.jade
create : testupdate/routes
create : testupdate/routes/index.js
create : testupdate/public/javascripts
create : testupdate/public/images
create : testupdate/public/stylesheets
create : testupdate/public/stylesheets/style.css

dont forget to install dependencies:
$ cd testupdate && npm install

$ cd testupdate
$ npm install
jade@0.17.0 ./node_modules/jade
├── mkdirp@0.2.1
└── commander@0.2.1
express@2.5.1 ./node_modules/express
├── qs@0.3.2
├── mkdirp@0.0.7
├── mime@1.2.4
└── connect@1.8.0
$ node app.js
Express server listening on port 3060 in development mode

All set!

Handling local versions in an app (in node_modules)

Yeah! Everyone talks about how easy to install, but no-one about how to manage versions, especially new stable versions. Also, what I didn't cover is changing the express version, etc., in an application itself, that is, changing the local versions: edit version numbers in package.json and then do a "npm install" (do this on git topic branch, or with backup). Another alternative of course is the npm link command to link global versions to local ones in node_modules; but that is dangerous when you want to pin back versions, especially in production.

Victor Kane