Skip to content

S8: NPM. Paquetes para node.js

Juan Gonzalez-Gomez edited this page Mar 22, 2022 · 4 revisions

Sesión 8: NPM. Paquetes para Node.js

  • Tiempo: 2h (50 + 50min)
  • Fecha:
  • Objetivos de la sesión:
    • Instalar paquetes a través de NPM
    • Creación de proyectos Node
    • Colores en la consola
    • Introducción a Express.js

Contenido

Introducción

La comunidad ha creado muchos módulos para node, que no vienen en la instalación oficial, pero que podemos descargar, instalar y utilizar para realizar nuestras aplicaciones web. Node incorpora un gestor de paquetes, el npm, que nos facilita la instalación y gestión de los módulos externos a usar

Jerarquía de módulos

Node utiliza el motor de Javascript V8 de Google, que es software libre y está implementado en C++. Se pueden acceder a funciones y objetos disponibles en tres tipos módulos: Módulos internos, módulos de Node y módulos externos

Módulos internos

Están disponibles globalmente. No hay que hacer nada especial para usarlos: simplemente están ahí 😀️. Hay uno que conocemos, y que hemos utilizado mucho: console. Estos son ejemplos de módulos internos:

  • Console: Objeto que contiene métodos para mostrar información en la consola. Típicamente se usa para la depuración de nuestros programas

  • Process: Contiene información sobre el proceso Node usado, así como métodos para controlarlo

Por ejemplo, usando process podemos conocer en qué plataforma se está ejecutando nuestra aplicación, qué procesador se está usando o desde qué directorio se ha arrancado, por ejemplo:

> process.platform
'linux'
> process.arch
'x64'
> process.cwd()
'/home/obijuan'

Módulos de Node

Al instalar Node, ya se incorporan una serie de módulos. Algunos ya los conocemos: HTTP, fs, url... Para usarlos es necesario importarlos en nuestra aplicación, utilizando la instrucción require().

const http = require('http');

Pero a parte de esto, no hay que hacer nada más. Los módulos están listos para usarse

Módulos externos

Son módulos creados por otras personas, y que no forman parte de Node. Para poder usar módulos externos debemos instalarlos primero. Los módulos externos se sitúan en la carpeta node_modules, dentro de nuestro directorio de trabajo

Una vez que ya están instalados correctamente, utilizamos require() para importarlos, igual que los módulos de Node

Por ejemplo, para utilizar el módulo de colores (colors) lo importamos así:

const colors = require('colors');

En las próximas secciones veremos cómo instalarlo y como usarlo

NPM: Gestor de paquetes

Para instalar los módulos fácilmente existen unas herramientas conocidas como gestores de paquetes. Nosotros utilizaremos npm que suele venir instalada con Node

Vamos a asegurarnos que la tienes instalada. Abre un terminal y ejecuta el comando npm -v. Si lo tienes instalado, te saldrá la versión que tienes. La versión que tengas instalada no es importante

$ npm -v
8.3.1

NPM es un gestor de paquetes en línea de comandos. Puedes encontrar información sobre todos sus comandos en este enlace: NPM CLI

Buscando paquetes

En el repositorio de npm existen miles de paquetes. Lo primero es encontrar lo que queremos. Normalmente los paquetes a instalar serán dependencias de otros paquetes, o bien nos lo pedirán en las instrucciones de instalación de alguna app

Si estamos buscando algo podemos utilizar el Buscador de paquetes npm situado en la parte superior

Como ejemplo, vamos a buscar algo relacionado con los códigos QR. En el buscador escribirmos qrcode. Obtenemos 967 paquetes...

La segunda opción parece interesante: qrcode-terminal. Nos permite sacar código QR por el terminal. Vamos a probarlo. Si pinchamos en el nombre del paquete nos aparece la información sobre el paquete. En el apartado install está el comando que hay que usar para instalar este paquete: npm i qrcode-terminal (Lo vemos en el próximo apartado)

Si bajamos por la pantalla obtendremos más información. Esta documentación depende del desarrollador que ha hecho el paquete, por lo que habrá paquetes con buena informacion y otros con muy mala

Instalando paquetes como módulos

Los paquetes que hay disponible suelen ser bibliotecas (librerías) que nos permiten incorporar funcionalidad a nuestras aplicaciones. Contienen los módulos (uno o más) que importaremos en nuestros programas usando require()

Vamos a instalar el paquete qrcode-terminal desde un directorio de trabajo. Ejecutamos este comando:

npm i qrcode-terminal

En el terminal nos aparecerá algo como esto:

Tras la instalación, en nuestro directorio de trabajo (npm-test), que inicialmente estaba vacío, habrán aparecido dos elementos: la carpeta node_modules y el fichero package-lock.json

  • node_modules: Es la carpeta donde se instalan todos los módulos de los paquetes. Si entramos, vemos que se ha creado la carpeta qrcode-terminal, y dentro de ella hay más cosas

  • package.json: Fichero con información sobre nuestro proyecto (Lo editaremos en las siguientes secciones)
  • package-lock.json: Describe el árbol de dependencias generado para que en otras máquinas se pueda replicar igual (sin tener que guardar en el repositorio el propio arbol de dependencias)

Ahora que ya está instalado, lo podemos importar en nuestros programas usando require(). Vamos a hacer una prueba rápida desde el intérprete de node. Los comandos que vamos a teclear son estos (te los pongo aquí para que puedas hacer copy & paste):

$ node
const qrcode = require("qrcode-terminal");
qrcode.generate("Holi!");

Esto es lo que obtenemos en el terminal:

Ha importado correctamente el módulo qrcode-terminal

Desinstalando los módulos

Los módulos instalados se eliminan con el comando npm r <nombre-paquete>. Siguiendo con el ejemplo anterior, vamos a eliminar el módulo qrcode-terminal

npm r qrcode-terminal

Esto es lo que vemos al ejecutarlo:

Y si ahora echamos un vistazo observamos que dentro del directorio node_modules se ha eliminado la carpeta qrcode-terminal

Instalando paquetes globalmente

Los paquetes también se pueden instalar globalmente en nuestro sistema. De esta forma se intalarán los ejecutables que traiga, y los podremos usar como cualquier otro programa instalado en nuestros sistema, y no sólo las bibliotecas para desarrollar

Por ejemplo, si instalamos el paquete qrcode-terminal de manera global, tendremos acceso en la línea de comandos al programa qrcode-terminal para generar códigos QR directamente

npm i -g qrcode-terminal

(Ahora el paquete NO se ha instalado dentro de la carpeta node_modules en mi diretorio de trabajo)

Desde la línea de comandos podemos ahora ejecutar el comando: qrcode-terminal "Hola"

Desinstalando paquetes globales

Para desinstalar los paquetes que previaemtne se han instalado globalmente hay que ejecutar el comando: npm r -g <nombre-paquete>

Con este comando desintalamos el qrcode-terminal:

npm r -g qrcode-terminal

El paquete colors: Imprimiendo en colores en el terminal

Vamos a practicar con el paquete colors, que nos permite imprimir mensajes en diferentes colores en la consola, y que nos vendrá bien para resaltar las trazas al depurar nuestro código

Primero lo instalamos en un directorio de trabajo, donde vamos a poner los ejemplos de esta sesión (elige el nombre que quieras)

npm i colors

Ejemplo 1: Imprimiendo en colores

El módulo colors añade nuevas propiedades a las cadenas para imprimirlas en color: .yellow, .red, .blue....

//-- Ejemplo de uso del módulo externo colores
//-- Hay que instalarlo con npm primero
const colors = require('colors');

console.log("Holiiiii".yellow);
console.log("Esto es rojo".red)
console.log("Y esto rojo resaltado...".red.bold);
console.log(('En arco iris...').rainbow);
console.log('Negro sobre blanco...!'.black.bgWhite);

Proyectos en Node.js

Cuando creas una aplicación con node, no sólo tienes tus ficheros fuente .js, sino que también tienes dependencias con módulos externos. Además, cada proyecto está creado por uno o varios autores, con una licencia determinada. Es decir, que en los proyectos de node tienes los siguientes elementos:

  • Tus ficheros fuente (.js)
  • Dependencias externas
  • Información sobre el proyecto (autores, licencia, documentación, enlaces...)

La información sobre el proyecto se pone en el fichero package.json, que está en formato JSON. La idea es que este proyecto se pueda subir a un repositorio de paquetes y que otros lo puedan instalar fácilmente con npm. Para ello es necesario aportar información adicional

En la documentación de NPM puedes encontrar más información sobre el fichero package.json

Ejemplo 2: Creando mi primer proyecto

Cada proyecto nuevo hay que colocarlo en su propio directorio. Hasta ahora poníamos todos los ficheros .js en el mismo directorio. Sin embargo, en los proyectos, cada uno tiene sus propias dependencias y su propio fichero package.json, por lo que lo situamos en directorios separados

El ejemplo 2 lo ponemos en la carpeta Ej-02. Creamos este fichero package.json:

{
    "name": "ejemplo-2",
    "description": "Mi primer proyecto",
    "version": "0.0.1",
    "author": "Juan Gonzalez-Gómez (Obijuan)",
    "main": "Ej-02.js",
    "license": "GPL-3.0",
}

Normalmente tenemos un fichero package.json de referencia que copiamos y modificando los datos necesarios. Pero también se puede crear uno desde cero utilizando el comando npm init. En este caso nos pedirá ciertos datos por la línea de comandos y se creará el package.json inicial

En este proyecto queremos usar el módulo colors. Por tanto, desde el directorio Ej-02 ejecutamos el comando:

npm i colors

El fichero package.json se ha modificado. Se ha añadido la nueva dependencia: colors

{
    "name": "ejemplo-2",
    "description": "Mi primer proyecto",
    "version": "0.0.1",
    "author": "Juan Gonzalez-Gómez (Obijuan)",
    "main": "Ej-02.js",
    "license": "GPL-3.0",
    "dependencies": {
        "colors": "^1.4.0"
    }
}

Ahora, por último, creamos una primera versión del proyecto en el archivo Ej-02.js:

const colors = require("colors");

console.log("Mi primer proyecto!".yellow);

Lo ejecutamos normalmente. Esto es lo que obtenemos

Nuestro primero proyecto ya está listo. Ahora lo subimos al repositorio

Subiendo el proyecto al repositorio

En este proyecto hola mundo tenemos en total 3 ficheros y la carpeta node_modules.

Sin embargo, la carpeta con las dependencias, node_modules, NO HAY QUE SUBIRLA. Esta carpeta puede llegar a ser muy grande, guardando en ella todas las dependencias de nuestro proyecto, y las dependencias necesarias para que funcionen esas dependencias

Para que esta carpeta NO forme parte del repositorio debemos crear un fichero llamado .gitignore que situamos en nuestro directorio raiz del repositorio, cuyo contenido sea:

  • Fichero .gitignore:
node_modules/

De esta forma, git sabrá que ese es un fichero que NO se debe incluir en el control de versiones y nos saldrá en otro color en el VSCODE

Cualquier cambio que ocurra dentro del directorio node_modules, no se nos indicará en el VSCode. Es como si ese directorio NO existiese para el repositorio

Arrancando un proyecto

Nuestro proyecto está en el repositorio. Supongamos ahora que queremos trabajar con el proyecto desde otro ordenador diferente del que hemos usado para crearlo, o que otro usuario se clona nuestro repositorio y quiere probar nuestro proyecto. Para ponerlo en macha hay que instalar todas sus dependencias y luego arrancar el fichero principal desde node

Aquí es donde viene en nuestra ayuda el fichero package.json: Esa información está ahí. Las dependencias ya se han añadido automáticamente cuando se invocó el comando npm i colors. Ahora vamos a indicar qué es necesario para arrancar nuestro proyecto. En el fichero package.json añadimos un nuevo campo: scripts, que contiene a su vez el campo start, donde se indica qué comando hay que ejecutar para hacer funcionar nuestro proyecto:

{
    "name": "ejemplo-2",
    "description": "Mi primer proyecto",
    "version": "0.0.1",
    "author": "Juan Gonzalez-Gómez (Obijuan)",
    "main": "Ej-02.js",
    "license": "GPL-3.0",
    "dependencies": {
        "colors": "^1.4.0"
    },
    "scripts": {
        "start": "node Ej-02.js"
      }
}

Así, los pasos que debe seguir alguien que arranque el proyecto por primera vez serán estos:

  • Instalar las dependencias: Ejecutar el comando npm install
  • Arrancar el programa: Ejecutar este comando npm start
$ npm install
$ npm start

Esto es lo que nos aparece en la consola al hacerlo:

Express: Desarrollo rápido de aplicaciones web

Express.js es un paquete de node.js para el desarrollo rápido de aplicaciones web. Actualmente lo están usando en producción empresas como Paypal, Uber o IBM

Para probar Express en esta sesión vamos a seguir haciendo ejemplos .js sencillos (y no proyectos). Por ello instalamos express en el directorio de los ejemplos:

npm i express

En el terminal nos aparecerá esto:

Ejemplo 3: Mensaje de bienvenida

Creamos nuestra primera aplicación WEB "Hola mundo" desde cero con express. Simplemente definiremos el punto de entrada principal (/) y cada vez que se acceda a él se devolverá un mensaje de bienvenida. Este es el código:

  • Fichero Ej-03.js:
//-- Importar express
const express = require('express');

//-- Crear una aplicación web vacia
const app = express();
 
//-- Puerto donde lanzar el servidor
const PORT = 8080;

//-- Definir el punto de entrada principal de mi aplicación web
app.get('/', function (req, res) {
  res.send('Bienvenido a mi aplicación Web!!!');
})
 
//-- Lanzar el servidor
app.listen(PORT);
console.log("Servidor Express corriendo en puerto " + PORT);

Fácil... ¿No? 😀️

Ejecutamos el programa:

node Ej-03.js
Servidor Express corriendo en puerto 8080

En el navegador veremos esto:

Si accedemos a cualquier otro recurso, que no está implementado, obtendremos esto:

Express nos ha gestionado los errores

Ejemplo 4: Añadiendo otro punto de entrada

Añadir un nuevo punto de entrada es tan fácil como invocar la función app.get() pasándole como argumento el nombre del recurso. En este código hemos añadido el recurso /woala

//-- Importar express
const express = require('express');

//-- Crear una aplicación web vacia
const app = express();
 
//-- Puerto donde lanzar el servidor
const PORT = 8080;

//-- Definir el punto de entrada principal de mi aplicación web
app.get('/', function (req, res) {
  res.send('Bienvenido a mi aplicación Web!!!');
})
 
//-- Otra vista
app.get('/woala', (req, res) => {
    res.send('WOALA! Chuck Norris approved!! :-)');
    console.log("Acceso a /woala");
});

//-- Lanzar el servidor
app.listen(PORT);
console.log("Servidor Express corriendo en puerto " + PORT);

Lo probamos:

Ejemplo 5: Páginas estáticas

Añadir páginas estáticas es tan sencillo como crear un directorio y meter en él todos los ficheros a los que queramos que se tenga acceso. Para mostrar el funcionamiento usaremos una página con html, css y javascript. Estos son los ficheros que colocaremos en el directorio public (Pero le puedes dar el nombre que quieras)

  • Fichero test.html:
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="test.css">
    <script src="test.js" defer></script>
    <title>Test</title>
</head>
<body>
    <img src="logo-urjc.png" alt="Logo URJC">
    <p>Ejemplo de página estática </p>
    <input type="button" id="boton" value="Color del fondo">
</body>
</html>
  • Fichero test.css:
@import url("https://fonts.googleapis.com/css2?family=Roboto");

body {
    background-color: lightblue;
    font-family: "Roboto";
    font-size: 30px;
}
  • Fichero test.js:
const boton = document.getElementById("boton");
const body = document.getElementsByTagName('body')[0];

boton.onclick = () => {
    if (body.style.backgroundColor=="green") {
        body.style.backgroundColor="lightblue";
    } else {
        body.style.backgroundColor="green";
    }
}

Y también metemos en el directorio la imagen: logo-urjc.png

En el servidor lo único que tenemos que hacer es indicar que el directorio público contiene páginas estáticas. Esto lo hacemos añadiendo esta línea:

//-- El directorio publico contiene ficheros estáticos
app.use(express.static('public'));

El nombre del directorio con lo ficheros estáticos NO forma parte del recurso URL. Así, para acceder al fichero test.html usaremos la url: localhost:8080/test.html

Por lo demás, es igual que el ejemplo 4. El fichero Ej-05.js queda así:

//-- Importar express
const express = require('express');

//-- Crear una aplicación web vacia
const app = express();
 
//-- Puerto donde lanzar el servidor
const PORT = 8080;

//-- Definir el punto de entrada principal de mi aplicación web
app.get('/', function (req, res) {
  res.send('Bienvenido a mi aplicación Web!!!');
})
 
//-- Otra vista
app.get('/woala', (req, res) => {
    res.send('WOALA! Chuck Norris approved!! :-)');
    console.log("Acceso a /woala");
});

//-- El directorio publico contiene ficheros estáticos
app.use(express.static('public'));

//-- Lanzar el servidor
app.listen(PORT);
console.log("Servidor Express corriendo en puerto " + PORT);

En esta animación lo vemos en funcionamiento

Y por supuesto, también nos funcionará desde el móvil si nos conectamos a la IP de la máquina donde está corriendo el servidor:

Autor

Créditos

Licencia

Enlaces

TEORIA

Soluciones

LABORATORIO

Prácticas y sesiones de laboratorio

Práctica 0: Herramientas

Práctica 1: Node.js: Tienda Básica

Práctica 2: Interacción cliente-servidor. Tienda mejorada

Práctica 3: Websockets: Chat

Practica 4: Electron: Home Chat

  • L11: Home chat (26-Abril-2022)
  • L12: Laboratorio puro. NO hay contenido nuevo (9-Mayo-2022)
  • L13: Laboratorio/Tutorias. No hay contenido nuevo (10-Mayo-2022)

EXAMENES

Curso 2020-2021

Clone this wiki locally