Passaggio all'ora legale 31 marzo 2019 02:0003:00 sposta avanti l'orologio di 1 ora (si dorme 1 ora in meno)
Il modo migliore per scrivere applicazioni web per Node.js è quello di utilizzare un framework come Express.
Come sempre con i nuovi framework bisogna capire come iniziare. Per questo ci viene in aiuto express-generator che crea una strutttura base di un applicazione.
Prima di tutto va installato express-generator quindi apri la command line di node:
npm install -g express-generator
a questo punto puoi creare l'applicazione, posizionati in una directory e digita:
express sgartapp
questo comando crea una directory sgartapp con la seguente struttura:
/
+-- app.js
+-- bin
|   +-- www
+-- package.json
+-- public
|   +-- images
|   +-- javascripts
|   +-- stylesheets
|       +--- style.css
+-- routes
|   +-- index.js
|   +-- users.js
+-- views
    +-- error.jade
    +-- index.jade
    +-- layout.jade
fatto questo, quello che manca è express e le sue dipendenze. Per installarle digita:
cd sgartapp && npm install
Il comando npm install si occupa di scaricare i pacchetti da internet e e ogni pacchetto viene posizionato in una cartella sotto /node_modules. Per trovare l'elenco dei file da scaricare npm si basa sul file package.json. All'interno del file, nella sezione dependencies, sono riportati tutti package necessari con le relative versioni.
a questo punto per eseguirlo:
SET DEBUG=sgartapp:* & npm start
per vedere l'applicazione apri il browser su http://localhost:3000 o http://localhost:3000/users.
npm start esegue l'applicazione basandosi sul file package.json più precisamente la sezione scripts/start che è impostata a node ./bin/www
Questo è un esempio di file package.json:
{
  "name": "sgartapp",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "body-parser": "~1.13.1",
    "cookie-parser": "~1.3.5",
    "debug": "~2.2.0",
    "ejs": "~2.3.2",
    "express": "~4.13.0",
    "morgan": "~1.6.1",
    "serve-favicon": "~2.3.0"
  }
}
Express implementa il pattern MVC dove sotto /routes abbiamo i controlles mentre le view sono sotto /views.

Guardando nel dettaglio i singoli file dell'applicazione, il file /bin/www rappresenta l'istanza del webserver:
#!/usr/bin/env node

// moduli dipendenze
var app = require('../app');
var debug = require('debug')('sgartapp:server');
var http = require('http');

// imposta la porta su cui è in ascolto, se non indicata
// nella variabile di ambiente PORT, usa la 3000
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

// crea il server HTTP con il file /app.js che usa express
var server = http.createServer(app);

// mette il server in ascolto sulla porta indicata
// su tutte le interfaccie
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

// normalizza la porta in un numero, stringa o false
function normalizePort(val) {
  var port = parseInt(val, 10);
  if (isNaN(port)) {
    // named pipe
    return val;
  }
  if (port >= 0) {
    // port number
    return port;
  }
  return false;
}

// gestore dell`evento errori HTTP
function onError(error) {
  if (error.syscall !== 'listen') {
    throw error;
  }

  var bind = typeof port === 'string'
    ? 'Pipe ' + port
    : 'Port ' + port;

  // handle specific listen errors with friendly messages
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges');
      process.exit(1);
      break;
    case 'EADDRINUSE':
      console.error(bind + ' is already in use');
      process.exit(1);
      break;
    default:
      throw error;
  }
}

// gestore dell'evento HTTP "listening"
function onListening() {
  var addr = server.address();
  var bind = typeof addr === 'string'
    ? 'pipe ' + addr
    : 'port ' + addr.port;
  debug('Listening on ' + bind);
}
l'entry point dell'applicazione express è rappresentato dal file /app.js:
//carico i moduli necessari
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

//carico i moduli dell`applicazione (non va indicata l`estensione .js)
var routes = require('./routes/index');
var users = require('./routes/users');

var app = express();

// imposta l`engine delle view e il path (/views) 
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// da decomentare se si mette la favicon.ico in  /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());

//imposta la directory /public come static ovvero non gestita da express,
// ritorna i file così come sono anche i .js
app.use(express.static(path.join(__dirname, 'public')));

//inposta i path (routes) gestiti dell`applicazione
app.use('/', routes);  //mappo il controller /routes/index.js sulla root /
app.use('/users', users);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// gestori errori

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {}
  });
});

module.exports = app;
Il controller /routes/index.js contiene:
var express = require('express');
var router = express.Router();

/* implemento il metodo GET che ritorna la home page */
router.get('/', function(req, res, next) {
  //passo alla view /views/index.jade un oggetto (model)
  res.render('index', { title: 'Express' });
});

module.exports = router;
la corrispondente view /views/index.jade contiene:
extends layout

block content
  h1= title
  p Welcome to #{title}
di default express usa come template engine jade
In fase di creazione dell'applicazione è possibile usare altri template engine per le view. Per vedere quali engine sono supportati digita express -h:
C:\node>express -h

  Usage: express [options] [dir]

  Options:

    -h, --help          output usage information
    -V, --version       output the version number
    -e, --ejs           add ejs engine support (defaults to jade)
        --hbs           add handlebars engine support
    -H, --hogan         add hogan.js engine support
    -c, --css <engine>  add stylesheet <engine> support (less|stylus|compass|sas
s) (defaults to plain css)
        --git           add .gitignore
    -f, --force         force on non-empty directory
ad esempio per usare ejs
express --ejs sgartapp
e la view diventa
<!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>
con codice html in stile asp classic.