node

Node Version Manager

Node Version Manager is a simple bash script to manage multiple active Node versions. Why do you want to use it? If you like me, you want to try out the latest unstable version of the Node, but you still need to use the older and stable versions to develop and maintain your projects, then you should use NVM.

You can find out more information on NVM GitHub page, below are just my take on installing and using it.

Install

You can install NVM via the install script, but always do it the hard way by installing it manually:

$ git clone https://github.com/creationix/nvm.git ~/.nvm

Check out the latest version:

$ cd ~/.nvm && git checkout v0.7.0

Enable NVM:

$ source ~/.nvm/nvm.sh

Add this to ~/.bashrc to make it available upon login:

$ echo "\n# Enable NVM"           >> ~/.bashrc
$ echo 'source $HOME/.nvm/nvm.sh' >> ~/.bashrc

Enable Bash completion:

$ echo 'source $HOME/.nvm/bash_completion' >> ~/.bashrc

Try it by opening a new terminal:

$ nvm

Usage

Get help:

$ nvm help

Show current NVM version:

$ nvm --version

Display the currently active Node version:

$ nvm current

Install Node v0.10.28:

$ nvm install 0.10.28

The installed Node version will reside in ~/.nvm/v0.10.28.

List installed versions:

$ nvm ls
    .nvm
v0.10.28

Use a specific Node version:

$ which node
/usr/local/bin/node
$ node -v
v0.11.13
$ nvm use 0.10.28
Now using node v0.10.28
$ node -v
v0.10.28
$ which node
/home/chao/.nvm/v0.10.28/bin/node

Basically, NVM modified the search path.

$ echo $PATH
/home/chao/.nvm/v0.10.28/bin

To roll back:

$ nvm deactivate
/home/chao/.nvm/*/bin removed from $PATH
/home/chao/.nvm/*/share/man removed from $MANPATH
/home/chao/.nvm/*/lib/node_modules removed from $NODE_PATH

List Node versions available to install:

$ nvm ls-remote

Use .nvmrc file:

$ echo '0.10.28' >> .nvmrc
$ nvm use
Found '/home/chao/.nvmrc' with version <0.10.28>
Now using node v0.10.28
$ node -v
v0.10.28

Difference between require and fs in Loading Files

Node has a simple module loading system by using require.

A module prefixed with '/' is an absolute path to the file. For example, require('/home/marco/foo.js') will load the file at /home/marco/foo.js.

A module prefixed with './' is relative to the file calling require(). That is, circle.js must be in the same directory as foo.js for require('./circle') to find it.

Without a leading '/' or './' to indicate a file, the module is either a “core module” or is loaded from a node_modules folder.

http://nodejs.org/api/modules.html#modules_file_modules

We can also use it to load JSON files by simply specifying the file path. File path can be relative or absolute. Giving the following file structure:

1
2
3
4
5
6
.
├── app.js
├── data
│ └── file.json
└── lib
└── util.js

Let’s say the root path of the application is /home/marco. Use relative path from the file lib/util.js:

1
var json = require('../data/file.json');

This will load the JSON content from data/file.json, because the require system knows that the file is relative to the calling file lib/util.js. But when using file system functions, relative path is not treat the same way:

Relative path to filename can be used, remember however that this path will be relative to process.cwd(). - File System

process.cwd() returns the current working directory, not the root directory of the application nor the directory of the calling file. For example:

1
var data = fs.readFileSync('../data/file.json');

If your current working directory is /home/marco/myapp, the application root directory, you will get the following error message:

1
2
3
4
5
6
fs.js:410
return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);
^
Error: ENOENT, no such file or directory '../data/file.json'
at Object.fs.openSync (fs.js:410:18)
at Object.fs.readFileSync (fs.js:276:15)

Because process.cwd() is /home/marco/myapp, and reading file relative to this directory with ../data/file.json, Node will expect file path to be /home/marco/data/file.json. Therefore, the error is thrown.

The difference between require and fs in loading files is that if the relative path is used in require, it is relative to the file calling the require. If the relative path is used in fs, it is relative to process.cwd().

To fix the error in file system functions, we should always use absolute path. One thing we can do is:

1
var data = fs.readFileSync(__dirname + '/../data/file.json');

__dirname is “the name of the directory that the currently executing script is resides in” [dirname], and it has no trailing slash. The the structure looks odd, even though it works, but it might not work in all systems.

The correct solution here is to use path.join from Path:

1
var data = fs.readFileSync(path.join(__dirname, '../data/file.json'));

The path module “contains utilities for handling and transforming file paths”. The path.join function will call path.normalize to “normalize a string path, taking care of .. and . paths” [normalize], also see function normalizeArray in https://github.com/joyent/node/blob/master/lib/path.js on how the paths are normalized.

In conclusion:

1
2
3
4
5
6
// Use `require` to load JSON file.
var json = require('../data/file.json');
// Use `fs` to load JSON file.
var data = fs.readFileSync(path.join(__dirname, '../data/file.json'));
var json = JSON.parse(data.toString());

Defining Correct Environment for CoffeeScript in Cron

I have written a bunch of CoffeeScript scripts that I would like to run them regularly. Cron is certainly the right choice in many situation.

The default executable path recognized by cron is limited:

* * * * * echo $PATH > /tmp/log/cron.log

This cron job will recognize the following path:

/usr/bin:/bin

However the default executable path for Node.js is usually at:

$ which node
/usr/local/bin/node

Therefore, if you attempt to run a cron job:

* * * * * node -v > /tmp/log/cron.log 2> /tmp/log/cron.err.log

It will return an error, where the executable is not found:

bin/sh: 1: node: not found

The easiest way to solve it is by specifying the fully qualified path:

* * * * * /usr/local/bin/node -v > /tmp/log/cron.log

To ensure the process is installed, we can check the file existence and permission before launching it:

* * * * * test -x /usr/local/bin/node && /usr/local/bin/node -v

But when working with CoffeeScript, the same method does not working:

* * * * * /usr/local/bin/coffee -v 2> /tmp/log/cron.err.log

Because CoffeeScript binary (coffee) use the following format:

#!/usr/bin/env node

Which does not specify fully qualified path on the shebang line, and will result in:

/usr/bin/env: node: No such file or directory

We can compile CoffeeScript into JavaScript and use fully qualified node executable. But this is not necessary. Since we are using Debian based system, which uses Vixie cron. It allows environment variables to be defined. We can make Cron aware of the custom path in environment variable:

* * * * * PATH=$PATH:/usr/local/bin coffee -v > /tmp/log/cron.log

Now the executable path include the one where both node and coffee commands reside.

We can also move it to its own line. But Cron is not shell, it does not expand the variable, so you have to specify all paths:

# Error: `PATH=$PATH:/usr/local/bin`
PATH=/usr/bin:/bin:/usr/local/bin
* * * * * coffee -v > /tmp/log/cron.log

The good practice is to set environment variables in a script:

1
2
3
4
5
6
#!/usr/bin/env bash
#
# This script is intended to be run as a cron job.
PATH=$PATH:/usr/local/bin
coffee -v

and run the script as a cron job:

* * * * * /path/to/script > /tmp/log/cron.log 2>> /tmp/log/cron.err.log

A New NodeJS Web Framework - Koa

Taking the first spin on Koa, a new web framework designed by the team behind Express.

Requirements

  1. Node v0.11.9 or higher is required for generator support.
  2. --harmony flag must be used when running Node.

Without the --harmony flag, genertor function cannot be defined:

function *fn() {
           ^
SyntaxError: Unexpected token *
    at exports.runInThisContext (vm.js:69:16)
    at Module._compile (module.js:432:25)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:349:32)
    at Function.Module._load (module.js:305:12)
    at Function.Module.runMain (module.js:490:10)
    at startup (node.js:123:16)
    at node.js:1031:3

So, set the --harmony flag in shell alias:

$ alias node='node --harmony'

To know more:

$ man node
--harmony (enable all harmony features (except typeof))
      type: bool  default: false

Harmony is the codename of ECMAScript 6, the next version of the standard.

Install

$ npm install koa

The footprint of the framework is small. Therefore, there is no executable binary like Express, and we do not need to install it globally.

Dependencies

Dependencies on version 0.2.1:

"dependencies": {
  "accepts": "~1.0.0",
  "type-is": "~1.0.0",
  "on-socket-error": "~1.0.1",
  "co": "~3.0.1",
  "debug": "*",
  "mime": "~1.2.11",
  "fresh": "~0.2.0",
  "koa-compose": "~2.1.0",
  "cookies": "~0.3.7",
  "keygrip": "~1.0.0"
}

Middleware

Middleware system is the core of either Express or Koa based application. This needs a separate post. Here just describes the difference in design.

In a simple assembly design, each unit passes control to the next one until the last one terminates and responses to the request:

    +-----+     +-----+     +-----+
--> |     | --> |     | --> |     | --o
    +-----+     +-----+     +-----+

Express middleware passes control to the next one like an assembly line, but each unit is capable of responding to the request:

       o           o           o
       |           |           |
    +-----+     +-----+     +-----+
--> |     | --> |     | --> |     |
    +-----+     +-----+     +-----+

Koa provides a traceback via generator, each unit is capable of working on the request twice instead of once as previous two designs. It is stack alike, where the first generator will also be the last one prior to responding to request:

       o
       |
    +-----+     +-----+     +-----+
--> |     | --> |     | --> |     |
    +-----+     +-----+     +-----+
       ^          | ^         |
       +----------+ +---------+

This is sort of an assembly loop, where the starting station is also be the ending station.

Usage

Here is one liner:

require('koa')().use(function *() { this.body = 'OK'; }).listen(3000);

app.use requires a generator function or function *(). Koa middleware uses this (context) instead of req and res in Express. It also encapsulates Node’s request and response objects. For example, this or context has the following properties:

[ 'request',     // Koa request
  'response',    // Koa response
  'app',
  'req',         // Node request
  'res',         // Node response
  'onerror',
  'originalUrl',
  'cookies',
  'accept' ]

Status and Body

Status can be used as a flag indicating whether a request has been processed or not:

app.use(function *() {
  console.log(this.status); // undefined
  this.body = 'processed';
  console.log(this.status); // 200
});

When the body is populated, status is automatically updated, probably via the nextTick method. So, we can use it as the flag to design a response such as a custom not found response.

Not Found

Create a custom Not Found in JSON content type:

app.use(function *(next) {
  yield next; // The operation is yet to start.
  if (this.status) { return; }

  this.status = 404;
  this.body = { message: 'Cannot find what you are looking for :(' };
});
app.use(function *() {}); // Do nothing to simulate not found.

Error Handling

Koa app is capable of catching the error event:

app.on('error', function (err, ctx) {
  // Log errors.
});

where ctx is a context instance. But you cannot modify the response body. This is more for server side logging and debugging purpose. The 500 Internal Server Error will be returned to the client.

We can use try..catch to define a custom error handling middleware:

app.use(function *(next) {
  try {
    yield next;
  } catch (err) {
    this.status = err.status || 500;
    this.body   = { message: err.message || 'Bad stuff happened!' };
    this.app.emit('error', err, this); // Enable error event handling
  }
});

Make sure to emit the error event and let the server log the error.

All non-operational middleware (e.g., not found or error) should be defined first, so it can be traced back as the last guards before sending response back.

Routing

Out of the box, Koa does not support routing, but it can be achieved via routing middleware, see examples.

Examples

Define an app with only one middleware generator function:

1
2
3
4
5
function *foo(next) {
console.log('foo');
this.status = 204;
}
require('koa')().use(foo).listen(3000);

Instead of using status code 200, we use 204 here, because the response contains no body. If using 200, the server does not know the total content length, will result in Transfer-Encoding: chunked header instead of Content-Length. See chunked transfer encoding.

This app simply prints out foo on the server side, and respond to a client with status code 204 and an empty body. We can even omit the next parameter, since we are not using it.

Now let’s use two middleware generator functions:

1
2
3
4
5
6
7
8
// Response: foo
function *foo(next) {
this.body = 'foo';
}
function *bar(next) {
this.body = 'bar';
}
require('koa')().use(foo).use(bar).listen(3000);

Since generator foo sets the body, generator bar will never be reached. We can change that by adding the yield:

1
2
3
4
5
6
7
8
9
10
// Response: bar
function *foo(next) {
this.body = 'foo';
yield next;
}
function *bar(next) {
this.body = 'bar';
yield next;
}
require('koa')().use(foo).use(bar).listen(3000);

This looks alot like Express, yeild next is similar to next(). Request travels through the middleware system first via foo then bar. But actually by using generator, it also returns back to foo as foo->bar->foo:

1
2
3
4
5
6
7
8
9
10
11
// Response: foo again
function *foo(next) {
this.body = 'foo';
yield next;
this.body = 'foo again';
}
function *bar(next) {
this.body = 'bar';
yield next;
}
require('koa')().use(foo).use(bar).listen(3000);

This is similar to a stack alike request model, where the first middleware should also be the last middleware to touch the request. There is a no-op middleware in the end to catch the last yield next produced by bar middleware generator and traces back the stack.

Debugging

Set environment variable DEBUG=koa* to enable Koa specific debugging information in development environment:

$ DEBUG=koa* node app.js

You will see a list of middleware. If a middleware is an anonymous function, we can set ._name to define a custom name:

function *foo(next) {
  // Middleware definition starts here.
}
foo._name = 'bar';
app.use(foo);

The middleware name will be bar instead of foo.

Resources

  1. Koa
  2. Koa | GitHub
  3. Koa Quick Guide
  4. Koa Middleware List

Working with Big Number in JavaScript

JavaScript is only capable of handling 53-bit numbers, if you are working with a big number such as Twitter ID, which is using 64-bit number, then you need to find an external library to do that, otherwise, there will be precision lost:

> num = 420938523475451904
420938523475451900
> num = 420938523475451904 + 1
420938523475451900
> num = 420938523475451904 - 1
420938523475451900

Here is one library to use in Node environment, install Big.js:

$ npm install big.js

Load the module:

> BigNum = require('big.js')
{ [Function: Big] DP: 20, RM: 1 }

Use string to create the big number:

> num = BigNum('420938523475451904')
{ s: 1,
  e: 17,
  c: [ 4, 2, 0, 9, 3, 8, 5, 2, 3, 4, 7, 5, 4, 5, 1, 9, 0, 4 ] }
> num.toString()
'420938523475451904'

Perform addition:

> num.plus(1).toString()
'420938523475451905'

Perform substraction:

> num.minus(1).toString()
'420938523475451903'

There are other packages that yet to be tested:

Set Filename Path with process.cwd()

When working with file system in Node, you will need a fully qualified filename to do things like reading the content of a file:

require('fs').readFile(filename, function (err, data) {});

If you have the following directory structure:

.
├── app.js
├── data
│   └── file.txt
└── lib
    └── reader.js

There are two ways to read the content of data/file.txt from lib/reader.js:

Use the current directory of the script __dirname:

filename = __dirname + '/../data/file.txt';

or with path.join to normalize the resulting path:

filename = path.join(__dirname, '../data/file.txt');

The second method is to use the current working directory of the process process.cwd():

filename = process.cwd() + '/data/file.txt';

The second approach is more portable. If you move lib/reader.js to lib/utils/reader.js, no code change will be needed. But make sure the directory of the Node process is the application root directory where node app.js is being issued.

Why Shebang?

Frequently the initial two characters on the initial line of a script are: #!.

Why Shebang? Well, simple reason, because shell needs to know which interpreter to use when executing the script.

The sha-bang (#!) at the head of a script tells your system that this file is a set of commands to be fed to the command interpreter indicated. The #! is actually a two-byte magic number, a special marker that designates a file type, or in this case an executable shell script (type man magic for more details on this fascinating topic). Immediately following the sha-bang is a path name. This is the path to the program that interprets the commands in the script, whether it be a shell, a programming language, or a utility. This command interpreter then executes the commands in the script, starting at the top (the line following the sha-bang line), and ignoring comments. - Starting Off With a Sha-Bang

The shebang line is usually ignored by the interpreter because the # character is a comment marker in many scripting languages. Even the actual script is written with a different commenting character, such as in JavaScript:

1
2
#!/usr/bin/env node
// JavaScript stuff starts here.

Because the first line is interpreted by the shell, and the rest is passed into JavaScript interpreter, in this case, Node.

The syntax of shebang:

#! interpreter [optional-arg]

Whether there is a space between shebang character and the interpreter or not, it does not matter.

The interpreter must usually be an absolute path to a program that is not itself a script. The following are example interpreters:

1
2
#! /bin/sh
#! /bin/bash

More examples are via head -n 1 /etc/init.d/*.

The optional‑arg should either not be included or it should be a string that is meant to be a single argument (for reasons of portability, it should not contain any whitespace). - Shebang_(Unix)

We also frequently see the following shebang:

1
#!/usr/bin/env bash

That has to do with portability. Not every system install node or bash command in the same path. /usr/bin/env will search through user’s $PATH, and correctly locate the executable.

To conclude for Node, here is the format I am using:

1
2
3
4
5
6
7
8
#! /usr/bin/env node
// Title
// =====
//
// Markdown style description starts here.
'use strict';

Preserve command history in Node REPL

Node REPL (Read-Eval-Print-Loop) is a standalone JavaScript interpreter for Node. To invoke it, simply type:

$ node

However, after exit and re-enter the REPL, all the previous commands are lost. This behaves very much different from what we expect from shell.

To maintain a persistent history, we can use rlwrap as suggested in this answer.

Install rlwrap:

$ sudo apt-get install rlwrap

Create an alias:

alias node='env NODE_NO_READLINE=1 rlwrap -s 1000 -S "node> " node'

Persistent history file is saved in:

~/.node_history

However, if by perserving the command history, Node REPL loses familiarity of color output and tab completion. This is a trade-off. To get around this problem, we can roll our own REPL or use an alternative. The best alternative I have found so far is also the one I am already using: CoffeeScript (see 1.6.3 change log). There is a history command built-in:

$ coffee
coffee> .help
.break  Sometimes you get stuck, this gets you out
.clear  Break, and also clear the local context
.exit   Exit the repl
.help   Show repl options
.history        Show command history
.load   Load JS from a file into the REPL session
.save   Save all evaluated commands in this REPL session to a file

Share JavaScript Code between Browser (front-end) and Node (back-end)

One of the benefits coding in JavaScript is the ability to share code between
browser (front-end) and Node (back-end) environments.

To share code between two different environment, first need to understand what
are specific to browser and what are specific to Node. Shared code should be
agnostic to both environments.

In browser environment, there is an obvious one: window object. In Node
environment, there are a few objects that are not globally defined in browser:
global, process, module, exports and more, see global objects. All
these variables work, but exports is preferred.

1
console.log('Hi ' + (typeof window !== 'undefined' ? 'browser!' : 'Node!'));

Once environment is identified, then it is just the matter of writing style,
either browser style or Node style.

For example, writing in Node style by passing the exports as the parameter:

1
2
3
4
5
(function (exports) {
var foo = exports.foo = {};
// Node style code goes here.
}(typeof exports === 'undefined' ? this : exports));

By using browser style, here is an example from the annotated source code of
Underscore:

1
2
3
4
5
6
7
8
9
10
11
// Export the Underscore object for Node.js, with backwards-compatibility
// for the old require() API. If we're in the browser, add _ as a global
// object via a string identifier, for Closure Compiler "advanced" mode.
if (typeof exports !== 'undefined') {
if (typeof module !== 'undefined' && module.exports) {
exports = module.exports = _;
}
exports._ = _;
} else {
root._ = _;
}

To make it easier without concerning the backward compatibility:

1
2
3
4
5
6
7
8
9
10
11
(function () {
var foo = {};
if (typeof exports !== 'undefined') {
exports.foo = foo;
} else {
this.foo = foo;
}
// Browser style code goes here.
}).call(this);

this is the same as window object in the browser environment.

1
2
3
(function (window) {
// Browser style code goes here.
}(this));

One more thing, writing in CoffeeScript is even better, because the compiled
code is already wrapped in closure, fewer indentation is needed.

1
2
3
4
5
6
7
foo = {}
if exports isnt 'undefined'
exports.foo = foo
else
this.foo = foo
# Browser style code goes here.

Compile to JavaScript by CoffeeScript 1.6.3:

1
2
3
4
5
6
7
8
9
10
11
12
(function() {
var foo;
foo = {};
if (exports !== 'undefined') {
exports.foo = foo;
} else {
this.foo = foo;
}
}).call(this);

Everything will be encapsulated inside the foo object.