20.6. Express Generating a Static Site

Static web sites are simpler than dynamic ones. The HTML5 is as is, and does not change. So Why node? Because we need even static web sites to be served of course. In order to create a static web site we could do:

$ npx express-generator --no-view --git myStatic

   create : myStatic/
   create : myStatic/public/
   create : myStatic/public/javascripts/
   create : myStatic/public/images/
   create : myStatic/public/stylesheets/
   create : myStatic/public/stylesheets/style.css
   create : myStatic/routes/
   create : myStatic/routes/index.js
   create : myStatic/routes/users.js
   create : myStatic/public/index.html
   create : myStatic/.gitignore
   create : myStatic/app.js
   create : myStatic/package.json
   create : myStatic/bin/
   create : myStatic/bin/www

   change directory:
     $ cd myStatic

   install dependencies:
     $ npm install

   run the app:
     $ DEBUG=mystatic:* npm start

Giving us the skeleton infrastructure

$ tree myStatic
myStatic
├── app.js
├── bin
│   └── www
├── package.json
├── public
│   ├── images
│   ├── index.html
│   ├── javascripts
│   └── stylesheets
│       └── style.css
└── routes
    ├── index.js
    └── users.js

6 directories, 7 files

In a static website routing is in the pages, ie the HTML5 files temselves. Therefore routing is not done by the server. This means that the following adaptations may be made

var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
/*
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
*/
var app = express();

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
/*
app.use('/', indexRouter);
app.use('/users', usersRouter);
*/
module.exports = app;

and the directory routes may removed.

The visible parts of the site will be presented from the index.html file because we chose a static site without view engine. Hence no view folder with content.

The package.json

{
  "name": "mystatic",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "cookie-parser": "~1.4.4",
    "debug": "~2.6.9",
    "express": "~4.16.1",
    "morgan": "~1.9.1"
  }
}

Now do

$ cd myappStatic
$ git init --initial-branch=main

Initialized empty Git repository in /home/nml/tmp/myStatic/.git/

$ npm install

added 53 packages, and audited 54 packages in 2s

found 0 vulnerabilities

$ npm start

The browser is then pointed at the designated port, and we see welcome screen.

Figure 20.2. The resulting Express Site
The resulting Express Site

Every Express application has an app.js module configuring the application with various external modules for use in the application. This external software is attached to the app object which is the shared.

The user of the app is the bin/www, a JavaScript file that we don't edit directly. With respect to the native Node.js we have worked with so far, app.js, and bin/www are two JavaScript files corresponding what we have called main.js, and bin/server.js before.

We have seen the file structure from the early project above.

Example 20.6. The app.js File
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
/*
var indexRouter = require('./routes/index');    // expendable in static
var usersRouter = require('./routes/users');    // expendable in static
*/
var app = express();

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
/*
app.use('/', indexRouter);                      // must go if undef
app.use('/users', usersRouter);                 // must go if undef
*/
module.exports = app;

The bin/www is a JavaScript file in spite of the lacking.js filename suffix. It is not particularly interesting in that we never edit it.

Example 20.7. bin/www

This file www is a JavaScript file despite its lacking .js suffix. It is hidden away in the www directory because we very rarely edit it. Only a small fragment from the top is shown here:

#!/usr/bin/env node
...

/**
 * Get port from environment and store in Express.
 */

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

/**
 * Create HTTP server.
 */

var server = http.createServer(app);

/**
 * Listen on provided port, on all network interfaces.
 */

server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
...

It says, among other things that, if the system variable PORT is found, its value will be the server's listening port. If not found it defaults to port 3000.