En el post anterior vimos como es el trabajo básico con express, creamos una API que respondía a un método get y nos devolvía un mensaje, con eso más o menos ya tendríamos que tener una idea de como es el trabajo con node usando otro tipo de métodos (get,post,put,..)(con la ayuda de la documentación oficial), más adelante haremos ejemplos mucho más complejos, conectándonos a Bases de datos, devolviendo JSON, usando JSON Web Token para autenticar usuarios...... pero antes de todo esto vamos a ver como se estructuraría un proyecto de Node+express y para ello nos vamos a valer de una herramienta llamada Express Generator que básicamente nos crea toda la estructura de carpetas y ficheros básicos que debería tener cualquier proyecto de este tipo.
Lo primero de todo es instalarla con npm de manera global ya que no nos serviría como proyecto si no tenemos proyecto......
npm install express-generator -g
Una vez instalada podemos hacer
express -h
Y vemos que opciones tenemos a la hora de crear nuestro proyecto
Como véis podemos indicarle varios engines html(precesadores de html que gestionan la parte dinámica como datos de base de datos, etc, en el servidor y lo envían ya construido al cliente), css (más o menos mismo concepto) o si queremos añadir un fichero gitignore a nuestro proyecto directamente(muy útil por cierto). Cada uno debería elegir las opciones con las que se sienta más cómodo (o las que nos obligue el proyecto).
Para generar un proyecto nuevo es suficiente con escribir express nombreDeProyecto
express ninja_project
Esto nos creará algunas carpetas con varios ficheros en ellas
Lo primero miremos el fichero package.json para ver que nos ha configurado por defecto. Tendríamos que tener algo similar a esto
{
"name": "ninja-project",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"body-parser": "~1.17.1",
"cookie-parser": "~1.4.3",
"debug": "~2.6.3",
"express": "~4.15.2",
"jade": "~1.11.0",
"morgan": "~1.8.1",
"serve-favicon": "~2.4.2"
}
}
Lo primero destacable que vemos es que nos ha creado un script llamado start donde tiene toda la pinta que es el punto de entrada de nuestra aplicación. A continuación vemos como nos ha seleccionado varias dependecias para ser instaladas, por ejemplo body-parser herramienta para parsear los elementos del body de una petición (se encontraría dentro del request que vimos en el post anterior, exactamente en request.body) o morgan el logger que ya vimos.
A continuación tendríamos que instalar las dependencias de nuestro proyecto, por lo que dentro de la carpeta ninja_project ejecutamos
npm install
Esto nos instala, todas las dependencias que tenemos en nuestro package.json y también las dependencias de estas, básicamente un montón de dependencias jejejeje
Con esto ya tendríamos todo listo para empezar, pero antes veamos un poco que es lo que nos ha configurado, primero de todo nos vamos al fichero por el que comenzaría nuestra aplicación bin/www.
En general supongo que al verlo os haréis una idea, resumiendo mucho este fichero es el que nos configura la aplicación para que escuche en algún puerto, veamos un poco como lo hace.
Lo primero a tener en cuenta es que requiere app, es decir, el fichero app.js de la raíz del proyecto. Este fichero básicamente es la instancia de express con algunas de sus configuraciones como son los módulos que va necesitar
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');
var index = require('./routes/index');
var users = require('./routes/users');
donde se encuentran las vistas y cuál es el engine para procesar y mostrar estas vistas como html
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
nivel de logs, la instanciación o configuración de algunos módulos y donde están los ficheros estáticos(en general siempre estan en una carpeta public o similar)
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
viene con escuchas de tipo get (son los requires de la carpeta routes, mirarlos y veréis como son de sencillitos, más abajo los vemos)
app.use('/', index);
app.use('/users', users);
Nos configura también una respuesta 404, es decir, página no encontrada si recibe un path url que no existe y se lo pasa a la ultima parte que es el error handler
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
Como véis una configuración bastante sencilla por parte del fichero app.js, continuemos con nuestro bin/www.
Lo siguiente requiere el módulo de debug y de http con la intención de configurar el puerto de escucha de la aplicación(con la posibilidad de usar una variable de entorno con nombre PORT para usar otra que no sea el de por defecto) y por último lo inicia.
/**
* 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);
Tenemos alguna cosa más pero creo que eso es lo más importante, el resto del fichero supongo que se entiende (más o menos).
Veamos ahora lo que tenemos en routes, miremos por ejemplo index.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;
Tiene instanciado la propiedad router, a la que le configura un manejador en la url raíz que lo que que hará como respuesta(el parámetro res del callback) es rendear la vista index pasándole el título Express.
Veamos la vista index.jade (si lo habéis dejado por defecto será jade si no aparecerá otra cosa)
extends layout
block content
h1= title
p Welcome to #{title}
Estp es una plantilla de jade que esta extendiendo de otra que es layout,jade pero a nosotros realmente nos interesa el title, este title es el parámetro que le enviamos desde el index.js, vamos a cambiarlo y al final veremos como queda, en el index.js ponemos esto por ejemplo (podéis poner lo que queráis)
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Ninja Project' });
});
module.exports = router;
Como véis es bastante sencillo lo que nos ha configurado express, ahora mismo ya podemos arrancar la aplicación con el script que hemos visto que tenia el package.json, es decir, con npm start y ya tendríamos nuestra app con express levantada, en el puerto 3000(si no hemos usado la variable de entorno para cambiarlo claro está).
Una vez ejecutada si accedemos con un navegador a localhost:3000 veríamos en el navegador algo similar a esto
Y en la consola, veríamos lo que ya vimos usando el módulo morgan
Por último comentar que aunque en el código lo llamen variables de entorno se pueden elegir los parámetros directamente con comandos, veamos uno que cambia todo
DEBUG=nombreApp:* PORT=3500 NODE_ENV=production npm start
Os cuento paso a paso:
- DEBUG=nombreApp:* Esto solo es para sacar más información en los logs, si ponemos nombreApp:* nos sacaría información de debug de todos los módulos pero podríamos indicarle un módulo específico para sacar solo información de el.
- PORT=3500: Como os podéis imaginar esto nos cambiar el puerto de ejecución del 3000 que viene por defecto, al que nosotros le pongamos.
- NODE_ENV=production: Por defecto node se ejecuta en modo desarrollo, básicamente provee de información más específica en los logs, ponerlo en producción simplemente es por evitar que en los logs aparezca información sensible en cuanto a datos o diseño de nuestra infraestructura u organización.
Para evitar tener que poner siempre parámetros largos recordar que podemos crear nuestros propios scripts por lo que podríamos crearnos otro que sea
"scripts": {
"production": "DEBUG=nombreApp:* PORT=3500 NODE_ENV=production node ./bin/www"
},
Y voilá ya tendríamos nuestro script de npm en producción, con debug y con un puerto custom.
Creo que para un post tenemos suficiente jejejeje, en el siguiente vamos a ver un poco más sobre las rutas, que podemos hacer con ellas, que significado implícito tiene cada tipo....y algunas cosas más ;)
Un abrazooooorrr





