Bienvenidos sean a este post, hoy continuaremos con la aplicacion Notas.
Como mencionamos al momento de hablar de Express, este al ser creado antes de ES6 solo implementa a CommonJS pero eso no quita que se pueda implementar, para ello necesitaremos el proyecto que iniciamos en el post anterior, en caso de no tenerlo simplemente sigan los pocos pasos mencionados y listo, en nuestra aplicacion debemos crear en el directorio raiz un archivo con el nombre de app.mjs y agregaremos este codigo inicial:
app.mjs
import { default as express } from 'express';
import { default as hbs } from 'hbs';
import * as path from 'path';
import { default as logger } from 'morgan';
import { default as cookieParser } from 'cookie-parser';
import { default as bodyParser } from 'body-parser';
import * as http from 'http';
import { approotdir } from './approotdir.mjs';
import { normalizePort,
onError,
onListening,
handle404,
basicErrorHandler
} from './appsupport.mjs';
import { router as indexRouter } from './routes/index.mjs';
const __dirname = approotdir;
Esta va a ser la parte inicial de nuestro archivo y en ella importamos una distinta cantidad de modulos, algunos ya conocidos como http o express, asi como unos que todavia no creamos, nuestro siguiente paso sera crear los modulos faltantes, el primero que crearemos sera la encargada del approotdir y para ello en el mismo directorio donde esta app.mjs crearemos uno nuevo llamado approotdir.mjs y le agregaremos el siguiente codigo:
approotdir.mjs
import * as path from 'path';
import * as url from 'url';
const __nombrearchivo = url.fileURLToPath(import.meta.url);
const __nombredir = path.dirname(__nombrearchivo);
export const approotdir = __nombredir;
Aqui basicamente importaremos dos modulos que usaremos para obtener el path y la url, en el segundo caso lo usaremos principalmente para obtener el nombre del archivo y crear el objeto con el cual contendremos al archivo, con este generado mediante el metodo dirname del modulo path obtendremos todo el directorio donde se ubica pero para eso necesitaremos el objeto con el nombre del archivo para finalmente exportar el objeto llamado nombredir pero lo haremos con el nombre del archivo, y este sera el que importaremos desde app.mjs, nuestro siguiente paso sera crear a appsupport.mjs y poder agregar los modulos faltantes, para ello deben crear un nuevo archivo, siempre en el directorio raiz de la aplicacion, con ese nombre y le agregaremos el siguiente codigo:
appsupport.mjs
import { port } from './app.mjs';
import { server } from './app.mjs';
export function normalizePort(val) {
const puerto = parseInt(val, 10);
if (isNaN(puerto)) {
return val;
}
if (puerto >= 0) {
return puerto;
}
return false;
}
Primero importaremos dos elementos del archivo que creamos anteriormente pero por el momento estos no existen pero no se preocupen que en un rato hablaremos sobre ellos, despues definiremos una funcion para poder exportarla y en este caso es una de las que importamos en app.mjs, esta se encargara de normalizar el puerto de conexion, en este caso recibira un valor y este lo pasaremos a una constante propia donde la convertiremos en entero y chequearemos primero si no es un numero, en caso de ser verdadero devolvera el valor informado sin convertirlo, en el siguiente condicional donde si es un numero este lo devolvera, y si no hubo coincidencia alguna devolvera un false, a continuacion agreguemos el siguiente bloque de codigo:
export function onError(error) {
if (error.syscall != 'listen') {
throw error;
}
const unir = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
switch(error.code) {
case 'EACCES':
console.error(`${unir} necesita mas privilegios`);
process.exit(1);
break;
case 'EADORINUSE':
console.error(`${unir} esta en uso`);
process.exit(1);
break;
default:
throw error;
}
}
Esta funcion tambien la exportaremos y sera la encargada de escuchar por los errores, primero veremos si el error recibido es distinto de listen y en caso de ser asi lo lanzara tal como lo recibio, despues definiremos una constante donde verificamos si el puerto recibido es de tipo string, en caso de ser verdadero nos notificara el named pipe que usamos de lo contrario informara el valor del puerto, despues mediante un switch verificaremos el codigo de error, el primer error es cuando no tenemos los permisos o privilegios necesarios para realizar la tarea, el segundo es para cuando el puerto o pipe estan en uso, en ambos casos usamos el texto de la variable que definimos anteriormente y el valor default solamente lanza el error que informamos, con esto comentado pasemos a agregar el siguiente bloque de codigo despues del anterior:
export function onListening() {
const direccion = server.address();
const unir = typeof direccion === 'string'
? 'pipe ' + direccion
: 'port ' + direccion.port;
console.log(`Escuchando en ${unir}`);
}
Esta se encargara de informarnos donde estara escuchando, primero definimos una constante donde almacenaremos la direccion del equipo, volvemos a definir una variable muy similar a la vista en el bloque anterior pero en este caso verificaremos si la direccion es un string, en caso de ser verdadero se considera que estamos usando un name pipe y lo indicaremos, en caso contrario usaremos la propiedad port que importamos desde server, por ultimo mostraremos en la consola en donde estamos escuchando, ahora pasemos a agregar el siguiente bloque de codigo:
export function handle404(req, res, next) {
const err = new Error('No encontrado');
err.status = 404;
next(err);
}
Esta funcion solo se encarga de manejar unicamente el error 404, para ello recibe tres valores que corresponden a la solicitud, la respuesta y el next para enviar el error mediante next pero aqui primero definiremos un objeto de error, le pasaremos el mensaje correspondiente y el codigo de estado, por ultimo lo enviamos al siguiente ciclo mediante el next, agreguemos el siguiente bloque de codigo:
export function basicErrorHandler(err, req, res, next) {
if (res.headerSent) {
return next(err);
}
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development'
? err : {};
res.status(err.status || 500);
res.render('error');
}
Esta sera una funcion que se encargara de manejar de manera muy basica el error, este recibira los tres argumentos del codigo anterior pero a su vez tambien el de error, lo primero que haremos sera verificar que se haya enviado los header de respuesta, en caso de ser asi devolveremos el error que recibimos como argumento, en caso de no ser asi almacenaremos el mensaje correspondiente al error pasado como argumento, despues estableceremos el error donde usaremos un condicional donde si env es igual a development y devolvera el error como tal y sino en blanco, por ultimo estableceremos el estado de la respuesta, sino existe uno estado de error se le pasa el de 500 y por ultimo enviaremos a error, recuerden que esto siempre debe ser asi, nuestro siguiente paso sera volver al archivo app.mjs y ahi agregaremos el siguiente segmento de codigo:
export const app = express();
export const port = normalizePort(process.env.PORT || '3000');
export const server = http.createServer(app);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
app.set('port', port);
hbs.registerPartials(path.join(__dirname, 'partials'));
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')));
app.use('/', indexRouter);
app.use(handle404);
app.use(basicErrorHandler);
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
Primero definiremos el objeto app con el modulo express que importamos, y tambien lo exportaremos para utilizarlo mas adelante, despues definiremos dos objetos que podremos exportar para indicar el puerto (port) y el servidor (server) a utilizar, y estos son los que exxportaremos para appsuport.mjs, siendo port uno que podemos enviarle mediante una variable de entorno y en caso de no hacerlo le estableceremos uno predeterminado, y server sera el creado mediante createServer, lo siguiente sera establecer tanto el directorio de las vistas como el engine que usaremos para las mismas, y estableceremos el valor de port para app, y luego estableceremos a los parciales, si no lo recuerdan son unos templates para ser reutilizados desde multiples lugares, despues tendremos un segmento donde aplicaremos muchos de los modulos que importamos al comienzo asi como muchos de los definidos en appsupport.mjs, por ultimo establecemos las instrucciones para que el servidor escuche las conexiones, si debemos hacer una comparacion entre app.mjs y appsupport.mjs tenemos lo mismo que en app.js pero en lugar de usar a CommonJS utiliza a ES6, pero todavia nos falta un archivo mas y este debemos crearlo en el directorio routes con el nombre de index.mjs y le agregaremos el siguiente codigo:
routes/index.mjs
import { default as express } from 'express';
export const router = express.Router();
router.get('/', async (req, res, next) => {
res.render('index', { title: 'Notas' });
});
En este caso simplemente convertiremos el archivo index.js de CommonJS a ES6, primero importaremos al Express y de este usaremos el metodo router, para finalmente indicarle que cuando nos envien a la direccion raiz renderizaremos o mostraremos al index y le pasaremos el titulo de Notas, antes de probarlo vayan al archivo package.json y modifiquen la seccion de scripts de la siguiente manera:
"scripts": {
"start": "cross-env DEBUG=* node ./app.mjs"
},
Esto hara que se utilice el archivo que creamos y no el original, con esto tenemos la base de nuestra aplicacion, veamos como trabaja mediante el siguiente video
Como podemos ver en el video ya funciona y vemos todo lo que nos devuelve cada vez que reciba una conexion, antes de terminar les dejo un archivo con todo el proyecto hasta ahora para que puedan verlo y utilizarlo, simplemente deben extraer el directorio en el PC y esta listo para usarse:
En resumen, hoy hemos visto como establecer las bases de nuestra aplicacion, asi como tambien convertimos la base de CommonJS a ES6, asi como hemos visto como trabaja ahora, espero les haya resultado util sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.


Donation
It’s for maintenance of the site, thanks!
$1.50
