Introducción al manejador de paquetes de JavaScript - NPM
¿Qué son paquetes?
En Ingeniería de Software se acostumbra reutilizar código de otros programadores y ni siquiera me refiero a trabajar en un proyecto ya escrito por alguno de tus compañeros de trabajo, sino utilizando las famosas librerías/paquetes/frameworks.
Imagina si todo el código de una biblioteca que deseas utilizar tuviera que ser copiado manualmente a tu proyecto, es decir, archivo por archivo para llamar a las funciones. ¡Qué pesadilla hacer eso!, incluso considerando que estas bibliotecas pueden contener hasta cientos de archivos y similares.
Aquí es donde entran las bibliotecas: un conjunto de software fácil de instalar que resuelve un problema frecuente. Por ejemplo: la biblioteca Cheerio, encargada de proporcionar una API que analiza el código HTML, lo que permite que el dev lo manipule fácilmente. Es ampliamente utilizada para leer datos que han sido adquiridos por scrapers.
Una vida más simple con el manejador de paquetes
Ahora pensemos: ¿cómo actualizar estos paquetes manualmente? Muchas veces dependen unos de otros y una simple actualización puede acabar rompiendo todos los demás paquetes. Una de las responsabilidades comunes de los manejadores o administradores de paquetes es precisamente ésa: actualizar las dependencias.
Algunas otras funciones:
- Asegurarse de que los paquetes se descarguen sin errores.
- Verificar el origen de los paquetes mediante firma digital (PKI).
- Administrar dependencias y evitar el infierno de dependencias, es decir, asegurarse de que todos los paquetes que necesita una dependencia x estén instalados de antemano.
- Publicar paquetes para que otros desarrolladores puedan instalarlos fácilmente.
Para comparar con nuestro primer escenario, pasamos de necesitar importar manualmente software de terceros en una aplicación a administradores de paquetes que manejan toda la complejidad relacionada con las dependencias. Estas características están a nuestro alcance a través de algunos comandos en la terminal.
NPM: el software de registro más grande que existe
En distintos lenguajes de programación e incluso en distintos sistemas operativos disponemos de manejadores de paquetes específicos. Algunos ejemplos:
- Maven para proyectos en Java, entre otros lenguajes.
- Pip para proyectos de Python.
- Go Modules en Golang.
- Brew para Mac.
- Chocolatey para Windows.
Cada uno de estos software tiene sus particularidades. Maven, por ejemplo, además de hacer lo que mencionamos anteriormente cuando hablamos sobre la funcionalidad de los administradores, también se encarga de la compilación, los informes y los lanzamientos. Se convirtió en una plantilla, un esqueleto para sus aplicaciones.
Para aplicaciones escritas en JavaScript tenemos NPM - Node Package Manager-. Es el repositorio de código más grande que existe para un solo idioma (se ha superado el hito de tener más de un millón de paquetes). El creador de NPM es Isaac Z. Schlueter, hoy CEO de NPM Inc. El administrador de paquetes fue creado por Schlueter para administrar sus propios paquetes cuando trabajaba en Yahoo en 2009. Pero fue a principios de 2010 cuando la primera versión útil estuvo disponible para sus usuarios.
NPM, además de ser un administrador de paquetes con las características que explicamos anteriormente (como administrar dependencias y/o permitir la publicación de paquetes) también es una herramienta CLI (interfaz de línea de comandos), es decir, permite igualmente crear y administrar paquetes a través de la línea de comandos usando la palabra clave npm. Otra característica disponible es el control de la aplicación con el comando npm run, del que hablaremos a continuación.
La estructura de package.json
Para utilizar NPM en tu proyecto, necesitas un archivo llamado package.json. Ve el ejemplo a continuación:
Hagamos un breakdown de las propiedades arriba:
- Version: Indica la versión actual de tu aplicación.
- Name: nombre de su aplicación.
- Description: descripción de tu aplicación.
- Main: punto de entrada de tu aplicación
- Private: si es verdadero, evita que se publique accidentalmente como público en el directorio de NPM.
- Scripts: establece una lista de scripts que se pueden ejecutar.
- Dependencies: la lista de todas las dependencias que se requieren para que tu aplicación funcione correctamente.
Las dependencias aquí se pueden destacar como una de las partes principales del archivo package.json. Es la información almacenada en esta palabra clave la que permite instalar todas las dependencias necesarias para el correcto funcionamiento de una aplicación X. Ten en cuenta que las versiones también se especifican, después de todo en la aplicación dada puede ser que una variante específica sea obligatoria. Hablemos más adelante sobre el comando npm install, que instala las dependencias automáticamente, lo que facilita el desarrollo y el uso compartido de aplicaciones.
NGP en la práctica
Para instalar en NPM, sigue los pasos para instalar en NodeJS, disponibles en la propia página de Node.
Hablemos de los comandos esenciales para usar la herramienta. Estos comandos deben usarse en la terminal de su sistema operativo y son parte de la CLI de NPM. Vamos a empezar desde el principio, ¿de acuerdo? Con npm inicial:
1) Npm init es un comando que iniciará una guía paso a paso para que configures tu proyecto NPM, aparecerán las siguientes opciones:
- Nombre del proyecto;
- Versión inicial;
- Descripción;
- Punto de entrada: hemos hablado de ello antes. Sería el archivo principal de la aplicación;
- Comando de prueba;
- Repositorio Git: repositorio donde se encuentra el proyecto;
- Palabras clave del proyecto: palabras clave relacionadas con el proyecto;
- Licencia.
Es importante mencionar que si no desea completar alguna información, se mostrará una sugerencia y puede presionar enter para aceptarla. Al final de este proceso se creará el archivo package.json.
Ejemplo de un paquete que se está creando:
2) Otro comando extremadamente importante para usar en cualquier administrador de dependencias es el utilizado para instalar paquetes. Estamos hablando de npm init. Su uso es sumamente básico: basta con teclear en tu terminal npm install. Por ejemplo: para instalar el paquete express como tenemos en el ejemplo anterior de package.json, se ejecutaría el siguiente comando: npm install express. En este caso, el paquete express disponible en el repositorio npm se instalará en la carpeta node_modules/ del proyecto donde se ejecutó el comando. El módulo también se agregará a sus dependencias en su paquete.json
Otra función que mencionamos anteriormente con respecto a la instalación de npm es su capacidad para instalar todos los paquetes que necesita una aplicación, es decir, las dependencias enumeradas bajo la palabra clave dependencies. Para realizar esta acción, simplemente ejecuta el comando de la siguiente manera: npm install, sin pasar ningún otro parámetro.
También puedes especificar la versión de la aplicación que deseas instalar. En el caso de la versión 4.16.3 de express (como se especifica en el paquete.json del ejemplo), ejecutaríamos de la siguiente manera: npm install express@4.16.3.
En mi workflow siempre usé un paquete npm llamado nodemon. Es muy útil mientras trabajas porque tiene la capacidad de notar cualquier cambio realizado en cualquier archivo de s¡tu proyecto y reiniciarlo automáticamente cuando sea necesario. Entonces, si tienes un error en el código y tu aplicación falla al iniciarse, simplemente cambia el código, guarda el archivo y tu aplicación se reiniciará automáticamente, sabiendo si el problema se solucionó.
Mencioné esta aplicación porque siempre la instalé globalmente en mis equipos. De esta forma, independientemente de la aplicación en la que estuviera trabajando, era posible utilizar nodemon. Esta es otra función muy útil del comando de instalación: instalar paquetes globalmente en tu computadora. Una advertencia sobre las aplicaciones instaladas de esta manera es que no se instalarán en tu ubicación de node_modules/application, sino en una carpeta de tu sistema. Por lo tanto, se pueden solicitar permisos de administradores para el proceso.
¡Casi se me olvida explicar cómo se hace la instalación globalmente! Simplemente ejecuta: npm install --global. En el caso de nodemon, siempre lo instalé usando: npm install -g nodemon (el -g actúa como un alias para la global flag).
3) Para actualizar paquetes y sus dependencias, se puede usar el comando de actualización. Ejecuta lo siguiente en su terminal: npm update.
4) En varios proyectos o incluso frameworks, es bastante común usar el comando de inicio de la siguiente manera: npm start. Esta ejecución es, tras bastidores, nada más que la ejecución de npm run start. Y hablaremos de algo que mencionamos brevemente: Control de flujo de aplicaciones a través de npm. Dentro de la lista de scripts en package.json puedes definir una serie de comandos para ser ejecutados usando npm. Por ejemplo:
De esa forma, los siguientes comandos estarán disponibles:
Éstos ejecutarán los comandos especificados que les asignen. Esto facilita el proceso de comandos muy comunes (como test, por ejemplo). Es decir, en lugar de verificar todos los comandos de prueba necesarios o, a veces, incluso los comandos que se ejecutarán antes, simplemente descarga el paquete y ejecuta npm run test.
Consejo para novatos con NPM: es posible usar alias/apodos para los comandos. Npm install, por ejemplo, se puede usar como npm i.
Consideraciones finales
¡Y eso es todo, amigos! Espero que hayas disfrutado esta guía para principiantes de NPM. Aquí abordamos cómo crear administradores de paquetes, su utilidad y cómo encaja el Administrador de paquetes de Node en todo este ecosistema.
Agrego que aun para el uso de Node.js y JavaScript en general existen también otros gestores. Investiga un poco sobre yarn y pnpm para ver las diferencias entre estos otros administradores.
¡Un abrazo y hasta la próxima!