Chapter 11: Transactions on the Web

11.2 A More Capable Web Server: Express.js

Node.js by itself is a very simple web server, as seen previously. But with the addition of an extensive framework of objects, properties, and methods, such as that provided by the Express package, Node becomes a full-fledged Web server that can be used for just about any application.

Documentation:

Installing Express.js
The Express Framework
Moving an Existing Web Site into Express

Installing Express.js

Express has its own ideas about the best way to structure your Web site, so it’s best to start with a fresh folder, install Express, copy your pages into it, and then modify them to make use of Express.

To install Express:

  1. In the command-line interpreter, change directory (folder) to where your new Web site folder will be located.
  2. To create the Express site framework we can use the Express Generator, a tool that is installed separately from Express. Ideally you will install it “globally” since it’s not actually part of your Web site:

    • Windows:

      Type this command in the  Node.js command prompt:

      npm install express-generator -g
      

      The files will be installed in your personal applications folder, AppData\Roaming, where it can be simply referenced.

    • Macintosh:

      If possible use administrator privileges to install Express Generator. Type this command in the  Terminal:

      sudo npm install express-generator -g
      

      and when prompted type in your password. The files will be installed in the usual location for nonstandard applications, /usr/local/bin.

      If you don’t have administrator privileges you can run these commands instead:

      export NPM_CONFIG_PREFIX=~/Applications/node_modules
      echo "export NPM_CONFIG_PREFIX=$NPM_CONFIG_PREFIX" >> ~/.bash_profile
      mkdir $NPM_CONFIG_PREFIX
      npm install -g express-generator
      

      Note that this will only work with the Mac’s default command-line interpreter, bash. If you are using a different shell then you can probably also figure out how to adjust the above commands.

  3. Now run the Express Generator with the name of the new Web site folder, e.g. by typing:

    express -e gnex
    

    This will create the folder (e.g. gnex) and install into it Express’ default structure, consisting of a number of files and folders that will be described shortly. With the -e option, it will also add a requirement to use the EJS template engine, also to be described shortly.

  4. One of the installed files is package.json, which provides configuration information for NPM, in particular about the different modules that the Web site depends on, such as Express itself:
    {
     "name": "gnex",
     "version": "0.0.0",
     "private": true,
     "scripts": { "start": "node ./bin/www" },
     "dependencies": {
         "body-parser": "~1.13.2",
         "cookie-parser": "~1.3.5",
         "debug": "~2.2.0",
         "ejs": "~2.3.3",
         "express": "~4.13.1",
         "morgan": "~1.6.1",
         "serve-favicon": "~2.3.0"
     }
    }
    
    To install these dependent modules, change directory into the Web site folder, e.g.
    cd gnex
    
    and type the command
    npm install
    
    The dependent modules will be placed in the subfolder node_modules.

Your Web site is now ready! The configuration file package.json also includes a script that you can use to easily start the server using NPM; again from the Web site folder, type the command:

npm start

⇒
> [email protected] start gnex
> node ./bin/www

To view the site, use your Web browser with the address http://localhost:3000:

Express

Welcome to Express

To stop the server, return to the command-line interpreter and type control-C (hold down the key control or ctrl and press C).

The Express Framework

Express’ default structure consists of these files and folders:

  • app.js — the main application
  • bin — a folder for other applications that you might wish to include, but also including the starting script www.
  • node_modules — a folder containing your application’s specific modules
  • package.json — a configuration file
  • public — a folder of static files such as images, scripts, and stylesheets
  • routes — a folder of JavaScripts that set up handling for particular locations on your Web site
  • views — a folder containing your Web pages

Express works as follows:

  1. The Web server is started with the script bin/www, which calls app.js, uses it to create a server, and starts the server;
  2. app sets up:
    1. The main document directory, e.g. views;
    2. The connection between document paths or routes (e.g. http://localhost:3000/index) and the scripts or routers that respond to requests for them (e.g. routes/index.js);
    3. The view engine that processes document templates;
  3. The routers respond to requests for particular document routes, process the template documents, and send the result to the browser that requested the document.
Starting the Server

The initial script, bin/www, has similarities to the previous simple server:

var app = require('../app');
var http = require('http');

var port = 3000;
app.set('port', port);
var server = http.createServer(app);
server.listen(port);

server.on('error', onError);
function onError(error) { .... }

Node’s require() function is used to first load the main application module app.js from the parent directory, followed by the http server module.

The object app sets a port property, a server is created using app, and then the server method listen is launched on this port.

The script concludes by setting an event listener that handles any errors that occur.

Server Setup

The main Express activity is set up in app.js, which begins by loading the dependent modules specified in the package.json file, and then creates the object app as an instance of the express module:

var express = require('express');
var app = express();

Your Web pages are stored in the folder views, as specified by the property views:

var path = require('path');
app.set('views', path.join(__dirname, 'views'));

The variable __dirname is set by Node to the folder of the current script, and path.join() produces a general reference to the folder views, e.g. C:\...\gnex\views on Windows and /.../gnex/views on Mac.

How the Server Responds to Document Requests

The basic server responsibility of responding to requests for documents is implemented by Express’ .use() method, which assigns particular router scripts to handle requests for particular document routes. For the default document at the server root, e.g. a request for http://localhost:3000/, the assignment is:

var routes = require('./routes/index');
app.use('/', routes);

The object routes is loaded from the script ./routes/index.js, and it will be run whenever a request comes in for a path beginning with /:

var router = express.Router();

/* GET home page. */
router.get('/', function(request, response, next) {
  response.render('index', { title: 'Express' });
});

The method router.get('/', callback) handles HTTP GET requests for the document / and passes them to its callback function for processing. The result is sent back to the Web browser.

Additional documents below the root folder / could also be listed in this module, e.g. router.get('/about', anothercallback).

Warning: the “root” folder for each router is the one assigned to it by app.use(), i.e. the statement app.use('/users', require('./routes/users')) will designate the route '/users' as '/' and '/users/local' as '/local' within users.js.

How the Server Processes Document Templates

The object response that is handed to these callback functions includes the method response.render(), which is used to process or render document templates. It looks for its first argument in the folder views, and then passes it through a view engine that was set earlier by app.js:

app.set('view engine', 'ejs');

Express’ default view engine is called Jade, but we chose another one when we created the framework with the command express -e, Enhanced JavaScript Templates (EJS), which is more understandable for most people.

The idea behind templates is that they allow you to set up a general structure for your pages, and then substitute in parameters that might vary from page to page. So in the default example above, the parameter title is set to the string 'Express', and that is inserted into the page that is being rendered, views/index.ejs, wherever the expression <%= title %> appears:

<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1><%= title %></h1>
    <p>Welcome to <%= title %></p>
  </body>
</html>

The result is then sent to the browser that requested the document:

Express

Welcome to Express

EJS has a number of options for substitution, some of use which we’ll see later. Check its documentation for a complete description.

Moving an Existing Web Site into Express

An existing Web site can be moved into Express without too much trouble:

  1. Copy all HTML files into the views folder, maintaining the same hierarchy;
  2. Change their .html endings to .ejs if you want to be able to subsitute values into them, e.g. from a user form or database;
  3. For each HTML file:
    1. Add a route in app.js, e.g. for about.ejs, add
      var about = require('./routes/about');
      app.use('/', about);
      
    2. Add a corresponding file in the folder routes, e.g. about.js:
      var express = require('express');
      var router = express.Router();
      /* GET home page. */
      router.get('/about', function(request, response, next) {
        response.render('about', { someEJSvariable: 'value' });
      });
      
  4. Copy your static files into public:

    1. CSS files into public/stylesheets; you can change the latter name to the current folder name if different, e.g. public/css;
    2. JavaScript files into public/javascripts; you can change the latter name to the current folder name if different, e.g. public/js;
    3. Image files into public/images; you can change the latter name to your current folder name if different, e.g. public/img.

    Your references should not include public but should begin with a root folder reference /, e.g. <link href="/css/styles.css"> will match the file public/css/styles.css.

results matching ""

    No results matching ""