Aprende Node.js con aplicaciones reales

Instalación y administración de paquetes

Instalación y administración de paquetes con npm

Junto a la versión de Node.js queda instalado el administrador de paquetes o librerías llamado npm; el cual es una utilidad de línea de comandos que permite instalar, actualizar y publicar paquetes para Node.js. Por defecto, npm utiliza el registro público (https://www.npmjs.com) para hacer todas las operaciones nombradas anteriormente; pero si una organización lo requiere, puede crear su propio registro privado para que sus paquetes no sean públicos y puedan ser consumidos de manera privada.

Por cada instalación de Node.js realizada, este instala una versión por defecto de npm para comprobar la versión instalada se ejecuta el siguiente comando:

npm -v

Pero lo anterior no significa que no se pueda actualizar la versión de npm que está asociada a la versión de Node.js seleccionada con nvm; si es necesario se puede actualizar la versión de npm con el siguiente comando:

npm install npm@latest --global

De allí en adelante, esa versión de npm estará actualizada para la versión de Node.js seleccionada con nvm.

Instalar paquetes locales

npm permite instalar paquetes de manera global, como por ejemplo el mismo npm o en general binarios que servirán de utilidades de línea de comandos. Pero el uso más común es instalarlos de manera local para un proyecto. Es importante resaltar que los paquetes locales se instalan en el directorio actual en el que se encuentre la sesión de la terminal; por ende, es siempre recomendado comprobar el directorio en que se encuentra ubicado en la sesión de la Terminal antes de ejecutar el comando de instalación.

Si desea conocer más información sobre un paquete instalado o no conoce el nombre específico de algún paquete, puede consultar el registro público de npm (https://www.npmjs.com).

En el proyecto de greeting se instala el paquete colors de manera local con el siguiente comando:

npm install colors

Nótese que dentro del directorio actual se ha creado un directorio llamado node_modules; este es utilizado por npm para almacenar todos los paquetes que se instalen en el directorio del proyecto y este mismo es usado para resolver las dependencias entre los diferentes paquetes. Si observa el contenido del directorio allí se encuentra el paquete instalado

A continuación se instala otro paquete llamado chalk, pero esta vez una versión específica, la número 4, que a su vez depende de otros paquetes; esto con el fin de poder observar dónde npm instala las dependencias de los paquetes. En el mismo directorio de trabajo ejecutamos el siguiente comando:

npm install chalk@4

Se puede ver el contenido del directorio de node_modules desde la terminal, con el siguiente comando:

ls node_modules

Si se observa nuevamente el contenido de node_modules, se puede notar que a su vez se han instalado las dependencias del paquete chalk, y todas las dependencias están al mismo nivel, este tipo de organización que utiliza npm se llama flat installation.

Para desinstalar un paquete, se utiliza el siguiente comando:

npm uninstall chalk

Con la instalación (o desinstalación), npm analiza los paquetes y sus dependencias entre ellos, creando así un árbol de dependencias, esto es muy útil para mantener la integridad del proyecto. Por lo tanto, si al desinstalar un paquete este tenía asociado una dependencia común con otro paquete, entonces el comando anterior no borra dicha dependencia.

Para más información de npm se puede consultar la guía oficial de uso.

Administración de versiones de paquetes

Puede observar que se ha creado un archivo llamado package-lock.json, es cual almacena la versión exacta de cada librería que se instala y todas sus dependencias. npm garantiza que cada librería que tiene dependencias en común cumpla todos los requisitos, al solucionar cualquier conflicto que pueda existir entre las diferentes versiones. Una vez realizado este trabajo queda plasmado en el archivo. Esto ofrece una gran ventaja a la hora de que otro usuario vuelva a instalar todas las dependencias del proyecto, ya que la resolución de las dependencias las realizará de manera determinística, garantizando así la instalación de la misma versión de las librerías y sus dependencias. Lo que no podría ser garantizado sin este archivo, porque a la hora de instalar nuevamente las librerías y dependencias del proyecto pueden existir nuevas o inclusive versiones depreciadas de estas.

El archivo package-lock.json está disponible desde la versión 5 de npm.

Utilizar paquetes locales

Para utilizar la librería recientemente instalada, se edita el archivo index.js de la siguiente manera:

const colors = require('colors/safe');

const args = process.argv.slice(2);
const [name = 'Friend'] = args;
const hour = new Date().getHours();

// Ask for hours range
if (hour >= 6 && hour < 12) {
  console.log(colors.yellow(`Good morning ${name}`));
} else if (hour >= 12 && hour < 18) {
  console.log(colors.green(`Good afternoon ${name}`));
} else if (hour >= 18 && hour < 23) {
  console.log(colors.cyan(`Good evening ${name}`));
} else {
  console.log(colors.blue(`Good night ${name}`));
}

Ejecutar la aplicación en la Terminal con el siguiente comando:

node index.js Gustavo

La extensión del archivo es opcional, la siguiente línea de comando es equivalente node index

Se puede observar en la consola el mensaje tiene el color indicado. Esto se puede lograr, ya que en la aplicación se utilizó el paquete de colors, que fue encontrado automáticamente en el directorio local node_modules.

Para conocer más información de la librería colors puede consultar su página web oficial.

Instalar y utilizar paquetes globales

Como se mencionó antes, los paquetes globales, como su nombre lo sugiere, no se instalan en ningún directorio local, se instalan a nivel global de la versión seleccionada de Node.js con nvm. Es decir, que al cambiar de versión de Node.js con nvm solo estarán disponibles los paquetes globales instalados de la versión seleccionada.

Al ser globales, pueden ser utilizados en cualquier proyecto o ejecutados desde cualquier directorio seleccionado desde la Terminal; lo anterior puede sonar a una enorme ventaja, pero es una práctica NO recomendada, ya que cada proyecto debe tener declarado en su manifiesto (el cual se verá con detalle en la próxima sección) todos los paquetes que necesita para ejecutar, tanto en desarrollo como en producción. En esta sección se realizará a modo de información.

Como ejemplo proceda a instalar el paquete ESLint que nos ayuda a comprobar la sintaxis de los archivos en JavaScript. Para instalarlo de manera global, se adiciona la bandera -g o --global

npm install --global eslint

Nótese que npm crea un acceso directo de archivo ejecutable del paquete para ser accedido desde la Terminal

Se crea en el directorio de trabajo un archivo temporal llamado temp.js, esto con el fin de añadir el error intencional para mostrar la utilidad del paquete ESLint, con el siguiente contenido:

var ups = ;

Se ejecuta ESLint para comprobar la sintaxis de nuestra aplicación temporal:

eslint --no-eslintrc temp.js

Muchos paquetes globales son inclusive utilizados para crear muchos scripts de flujos de trabajo local en el sistema.

Se obtiene el siguiente resultado:

1:11 error Parsing error: Unexpected token ;


1 problem (1 error, 0 warnings)

Para ESLint se pueden definir todas las reglas de sintaxis e inclusive extender de una guía de estilos ya existentes. Para mayor información puede visitar la Guía de inicio de ESLint.

Resolución de paquetes

Una interrogante importante es qué pasaría si se tiene un paquete instalado, tanto localmente como globalmente, ¿Cuál versión utilizaría Node.js? En este caso, Node.js busca el paquete en el directorio local del proyecto (node_modules); si no lo encuentra, procede a buscar el paquete en la instalación global y, finalmente, si no lo encuentra, muestra un error.

Otros administradores de paquetes

El hecho de que npm se instale automáticamente con la instalación de Node.js no quiere decir que sea el único administrador de paquetes. Yarn fue lanzado al público en el 2016 como uno de los proyectos Open Source de Facebook. Con una gran acogida, su característica principal es la velocidad de instalación de los paquetes debido a un enfoque determinístico.

Yarn utiliza el mismo archivo de manifiesto que npm (package.json), al igual que el directorio donde se instalan los paquetes (node_modules), por lo que se puede utilizar sin mayor cambios como administrador de paquetes en un proyecto de Node.js. Si es un proyecto existente, se recomienda eliminar el directorio de node_modules y hacer una instalación “limpia”. No se recomienda utilizar los dos administradores de paquetes npm y Yarn simultáneamente en el mismo proyecto.

Si se tiene instalado Homebrew en Mac OS, Yarn se puede instalar con el siguiente comando:

brew install yarn

E inclusive se puede instalar con npm con el siguiente comando:

npm install -g yarn

Para conocer más sobre las opciones de uso de Yarn puede visitar la Guía de uso de Yarn.