JavaScript as a Server-Side Scripting Language

By Neal Grosskopf, Software Engineering Director

Published: October 3, 2011

Why?

When considering a Server-side language many think of the popular and common ones like PHP, Perl, or .NET, however, a new alternative has risen in popularity that allows the execution of JavaScript on the server-side and utilizes Google’s V8 JavaScript Engine. Essentially, it is a set of libraries on top of Google’s V8 and It is named node.js.
The most intriguing feature of Node is in how it handles I/O threads. Their site states, “Node will show much better memory efficiency under high-loads than systems which allocate 2MB thread stacks for each connection.” The result of this is that the server is less likely to freeze up or hang under high-loads like it might with most of the common server-side scripting languages. This means that even novice programmers don’t need to worry about holding up the I/O.

With it’s unique I/O thread handling, Node will never have to pause or stop and wait for a process. If there is a setTimeout command, Node will just move past it and execute the other commands while the code in the setTimeout command is waiting to execute. For example the following code in Node:


setTimeout(function() {
console.log("world");
}, 2000)
console.log("hello");

Will have the same results as the following code in PHP:

echo “hello”;
sleep(2000);
echo “world”;

Notice the placement of the “hello” and “world” text in the Node JavaScript vs the PHP file. This is a very simplistic example of how Node can handle threads more efficiently which in turn means it can handle heavier loads and produce faster results.

Though Node is not DOM driven as it is not processed in the browser, it has a similar process object that is at the core of it’s functionality. This process object is global and can be used to access vital functions to Node. The developers of Node also took special care to name their functions similar to those of DOM driven JavaScript so the transition for a front-end JavaScript developer to Node’s process driven javascript is easier.

Installation

Node is ridiculously easy to install and comes with package installers for Windows and OSX environments and can be downloaded here.

Setup

The basic server setup of Node may be difficult to comprehend at first as the developer has to build some of the elements that Apache or IIS web servers have at their disposal out of the box. However, by having to do this, the server can be optimized to containing just the functions and elements that the developer needs without any extra bloat, this can contribute to speed and performance.

Setting up the initial web server is pretty painless and there is a good example setup on node.js’s site. Here is the code for the initial “Hello World” server:

var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(1337, "127.0.0.1");
console.log('Server running at http://127.0.0.1:1337/');

An important piece here is the .listen  command. This tells the node server what port to listen on (in our case 1337) as well as what IP to listen on (127.0.0.1). To start the server on the node above, navigate to the directory the node file is in and use the “node” command to run it, this should output something similar to below:

-> node /path/to/node/script.js
-> Server running at http://127.0.0.1:1337/

Now if you type the IP in above in your browser, you should see “Hello World” text displayed on the screen.

Basic Tutorial

Next, let’s setup some basic routing and a theme using a combination of Tom Crinson’s “A Gentle Introduction to Node.js” tutorial and Rob Searles’ “NodeJS Tutorial”. To start out with this, you will need to install the theme-ing tool mustache.js to your node server directory:

git clone https://github.com/janl/mustache.js/

Before you get theme-ing, a couple of changes are necessary. First, rename the folder from “mustache.js” to “mustache”. Second, as stated in Tom Crinson’s tutorial, you will have to open /mustache/mustache.js and change the following:

var Mustache = function() {

TO

Mustache = function() {

After the above is complete, create a node server file at the top level of your working directory and place the following code in it:

var sys = require('sys'),
fs = require('fs'),
Url = require('url'),
http = require('http'),
querystring = require('querystring');
require('./mustache/mustache');
//Step 2 code here
http.createServer(function (req, res) {
var url_parts = Url.parse(req.url);
var html = '';
switch(url_parts.pathname) {
case '/':
html = router['/'](req);
break;
case '/addTime':
html = router['/addTime'](req);
break;
default:
display_404(url_parts.pathname, req, res);
}
res.end(html);
function display_404(url, req, res) {
res.writeHead(404, {'Content-Type': 'text/html'});
res.write("<h1>404 Not Found</h1>");
res.end("The page you were looking for: "+url+" can not be found");
}
}).listen(8000);

This sets us up for loading a mustache template as well as completing some simple routing actions. Make sure you don’t forget the display_404 function, if this is missing the server may error out looking for a resource like the favicon.ico file.

To finalize our script, we will setup the router variable as well as the action variables and mustache.js templates. Place the code below where the comment states “Step 2 code here”:

var html_template = "<html><head><title>{{title}}</title></head><body>{{{content}}}</body></html>";
var form = function() {return "derp<div id='container'> \
<form method='post' action='/addTime'> \
<ul> \
<li> \
<label for='element_1'></label> \
<div> <input name='activity' type='text' value=''/> </div> \
</li> \
<li> \
<input type='submit' name='submit' value='Submit'/> \
</li> \
</ul> \
</form> \
</div>"};
var index_view = { title : "Time", content : form };
var add_time_view = { title : "Time", content : "Success" };
var indexAction = function(req){
return Mustache.to_html(html_template, index_view);
};
var addTimeAction = function(req){
var formData = null;
req.addListener('data', function (post) {
formData = querystring.parse(post.toString());
});
fs.open("timesheet.txt", "a", 0666, function(er, fd){
var timeStamp = Math.round(new Date().getTime() / 1000);
fs.write(fd, timeStamp+':'+formData['activity']+"\n", null);
});
return Mustache.to_html(html_template, add_time_view);
};
var router = { "/" : indexAction, "/addTime" : addTimeAction };

Last, create a text file in your node server directory named timesheet.txt. Now Navigate to http://localhost:8000 and enjoy!

James Fuller also has a great more in depth tutorial on setting up a Node web server with error catching and dynamic page loading.

Closing Notes

Node is a great and powerful server-side scripting tool that has the potential to destroy the worlds of the other server-side languages. It’s speed and threading techniques outshine all of the other languages and it makes for a fairly easy language to pick up for anyone who has JavaScript front-end skills.

It may not be wildly popular yet, but that does not mean it won’t be as common as PHP or .NET in the next few years.