My blog, as if written in Node.js - part 1.
Node.js is a server side JavaScript platform built on top of Google's V8 JavaScript engine. It is centered around a single-threaded, event based I/O, making it suitable for building scalable network programs. As such, building a blog does not really take advantage of Node's true strengths, but it does provide a familiar topic as the basis for our learning.
When getting started with Node, the choice of which Node modules to use is a little overwhelming. I had a quick look through a lot of then and tried to map out a stack for my application - I settled with: express.js web framework (which is built on Connect), EJS Embedded JavaScript templates and a Node Mysql module by Felix G. whom I know produces great quality work from all of his CakePHP contributions.
Installing Node.js
I recommend downloading the latest stable release. From there, explode it into a folder, and then:
./configure
make
make install
You should also install NPM (Node Package Manager). This should be as simple as:
curl http://npmjs.org/install.sh | sh
If you run into Permission Errors, then check out your options for resolving those in isaac's readme.
Installing the express web framework
I installed express using NPM via the following command:
npm install express
Project structure overview.

Before we get stuck into things, I've included a screenshot of my current project layout here, because it was one of the first things I came across and wasn't sure about.
Good project structure, and following conventions, are both incredibly important in producing a project similar to the way other developers would expect it.
I have free-styled a bit here, a little bit CakePHP inspired, a little bit gut-instinct. In reality, I will probably gain more exposure/experience and re-evaluate my project structure over time, ultimately incorporating it into my own project framework/scaffolding.
Don't worry about stubbing out the files based on this image - we will get there in good time.
The web server, server.js:
The very first thing the Node.js website teaches you, is how to write a basic web server using Node!
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World');
}).listen(8124, "127.0.0.1");
console.log('Server running at http://127.0.0.1:8124/');
I have chosen to use the Express framework, so my server is set up in a slightly different way, but the concepts are the same. The following is my web server setup:
// Import express, made available via NPM.
var express = require('express');
var app = express.createServer();
var PORT = 8080;
// Set the default view engine to EJS.
app.set('view engine', 'ejs');
// Configure the app.
app.configure(function() {
app.use(express.methodOverride());
app.use(express.bodyDecoder());
app.use(app.router);
app.use(express.staticProvider(__dirname + '/public'));
});
// [ Some code removed ]
app.listen(PORT);
console.log('Node.js web server listening on port: ' + PORT);
At this point, the code runs but will return an error.
Go on, test it out - node server.js and view the website: http://localhost:8080/
You should experience a: "Cannot GET /" error.
Let's look at a few concepts in the above snippet, before adding some code to fix the error.
- The convention for importing modules (or libs) is: var module = require('module');
- We can use __dirname to get the directory name of the script being executed.
- We can log (to terminal by default) using console.log(msg).
Adding developer friendly error messages:
Add the following snippet of code just before the: app.listen(PORT); line of code.
// Development.
app.configure('development', function() {
app.use(express.errorHandler({dumpExceptions: true, showStack: true}));
});
// Production.
app.configure('production', function() {
app.use(express.errorHandler());
});
With these in place, we can now run in development/production mode using:
NODE_ENV=production node server.js
Adding a basic route:
We are now going to add a basic route to our website/app.
Add the following snippet of code just before the: app.listen(PORT); line of code.
// Route :: /pages/hello-world
app.get('/pages/hello-world', function(req, res) {
res.render('pages/hello-world', {
locals: {
title: 'Hello World'
}
});
});
You will get the following error:
500 Error: ENOENT, No such file or directory '.../tonymilne/views/pages/hello-world.ejs'
Let's digest that - we told Express to render a template: 'pages/hello-world'.
Express has a views directory in which it looks for view templates, defaulting to: CWD/views.
We can modify this location using app.set('views', ...);
We told Express that we want our view engine to default to EJS for templates without extensions, when we wrote: app.set('view engine', 'ejs');
This allows us to leave off the extension and it will look for .ejs files automatically.
So, we need to add an empty .ejs file into our '/views/pages' directory called 'hello-world.ejs'.
We now get a similar error, this time because we are missing our default layout. We need to add another empty .ejs file into our '/view' directory called 'layout.ejs'.
A quick page refresh and we now get a blank page. I wonder why? Oh, that's right - all of our views are empty files!
Let's add some layout view code:
<html>
<head>
<title><%- title %></title>
</head>
<body>
<div id="page">
<%- body %>
</div><!-- end page -->
</body>
</html>
The main thing to note here is that we are passing JavaScript variables to the template and letting EJS render them for us using the <%- %> tags. It effectively means evaluate and print what is returned within the tags, similar to a PHP echo statement.
Now let's add the hello-world view code:
<h1>Hello World</h1>
A quick page refresh and we are greeted with the familiar: "Hello World".
To be continued...
In future post(s) within this series, I will be covering:
- using one route callback for multiple routes
- mysql connectivity from within Node.js
- and some more complex EJS techniques (including helpers & view partials with collections).