...

/

Project Solution: Node.js Application

Project Solution: Node.js Application

Now let us have a look at the files used in the Node.js app.

Node.js build process

Client-side files in the src directory are processed using npm scripts and output to a static directory. This is shared as a Docker volume so NGINX can serve HTML, CSS, and JavaScript requests without Express.js processing.

Production mode build

Production environment build scripts are defined in the package.json "scripts" section:

Press + to interact
"build:htm":
"pug -O ./src/html/data.json ./src/html/ -o ./static/",
"build:css":
"postcss src/css/main.css -o static/css/main.css --no-map",
"build:es6":
"rollup --config",
"build":
"npm run build:htm && npm run build:css && npm run build:es6",
"start":
"npm run build && node ./index.js"

npm run build is executed when the Docker image is built. This processes src files using pug, PostCSS, and Rollup.js to create optimized HTML, CSS, and JavaScript files in the static directory.

Development mode watch and build

Development mode watch scripts are also defined in the package.json "scripts" section:

Press + to interact
"watch:htm":
"pug -O ./src/html/data.json ./src/html/ -o ./static/ --pretty -w",
"watch:css":
"postcss ./src/css/main.css -o ./static/css/main.css
--map --watch --poll --verbose",
"watch:es6":
"rollup --config --sourcemap inline --watch --no-watch.clearScreen",
"watch:app":
"nodemon --trace-warnings --inspect=0.0.0.0:9229 ./index.js",
"debug":
"concurrently 'npm:watch:*'",

The watch options in the pug, PostCSS, and Rollup.js are used to monitor files and rebuild when necessary. Similarly, Nodemon watches for Node.js application file changes and restarts accordingly.

npm run debug is executed by Docker Compose. This launches concurrently, which executes all npm watch:* scripts in parallel.

Node.js Express.js application

The primary index.js application uses dotenv to parse database settings in the .env file and define environment variables:

// main application

'use strict';

// load environment
require('dotenv').config();

The ./lib/db.js module then initializes the database and exports a single getQuestion() function:

const
  // initialize database
  quizDB = require('./lib/db'),

Express.js is initialized with middleware functions to set the static directory, permit access from other domains using CORS, and ensure requests are never cached:

Press + to interact
// default HTTP port
port = process.env.NODE_PORT || 8000,
// express
express = require('express'),
app = express();
// static files
app.use(express.static('./static'));
// header middleware
app.use((req, res, next) => {
res.set({
'Access-Control-Allow-Origin': '*',
'Cache-Control': 'must-revalidate, max-age=0'
});
next();
});

It should not be necessary to set the express.static directory because NGINX will serve the files directly. However, you may need to connect to the Node.js application directly at 8000 or 9229 when debugging.

You ...