paint-brush
Por qué no necesita PNPM ni HILOby@bormando

Por qué no necesita PNPM ni HILO

Dmitrii Bormotov9m2024/07/23
Read on Terminal Reader

npm es un administrador de paquetes predeterminado para el ecosistema **Node.js**. Viene con el paquete de instalación, por lo que básicamente está listo para usar cuando instalas **Node.js** en tu máquina (o en cualquier proveedor de **CI** si configuras **Node.js** allí). Es estable y su velocidad es comparable a la de otros administradores de paquetes.
featured image - Por qué no necesita PNPM ni HILO
Dmitrii Bormotov HackerNoon profile picture
0-item

¡Hola a todos!


Estoy seguro de que has visto proyectos de Node.js usando diferentes administradores de paquetes, es decir:



Lo he visto yo mismo y he trabajado con todo lo anterior, pero siempre tuve una pregunta en mente: ¿qué impulsa a las personas/equipos a usar hilo o pnpm en lugar de npm ? ¿Cuáles son las ventajas? ¿Hay alguna desventaja?


Bueno… ¡descubrámoslo!

Reglas de comparación de desempeño

Decidí comparar npm , Yarn y pnpm en términos de su "velocidad"...


Verás 3 medidas a continuación:


  1. Genere un archivo de bloqueo sin caché.


  2. Instale dependencias de archivos de bloqueo existentes sin ningún caché.


  3. Instale dependencias de archivos de bloqueo existentes con caché global.


Hay dos tipos de caché:


  1. Global.

    Generalmente se almacena en el directorio de inicio del usuario (por ejemplo, ~/.yarn/berry/cache ).


  2. Local.

    Almacenado en el directorio del proyecto (fe, <project-dir>/.yarn ).


Si bien los casos de uso 2 y 3 son los casos de uso más comunes en mi experiencia, también tomé el n.° 1 por si acaso (aunque es un caso muy raro).


Utilicé un proyecto de muestra de create-react-app como ejemplo para los puntos de referencia.

npm

Es un administrador de paquetes predeterminado para el ecosistema Node.js. ¿Qué más decir? Viene con el paquete de instalación, por lo que básicamente está listo para usar cuando instala Node.js en su máquina (o en cualquier proveedor de CI si configura Node.js allí).


En mi opinión, eso es una gran “ventaja”: ¡no es necesario instalarlo por separado!


No hay nada extraordinario allí, simplemente... ¡funciona! Y no he visto ningún error importante a lo largo de los años: parece bastante estable y hace el trabajo.


Las características de npm que usé hasta ahora:


  1. Administrar dependencias (instalar, eliminar, actualizar)
  2. Publicar paquetes (privados, públicos)
  3. Paquetes de enlace local
  4. Administrar espacios de trabajo.

Administrar dependencias

npm almacena las dependencias en la carpeta node_modules de la raíz de su proyecto. Muy claro.


ℹ️ package-lock.json almacena información sobre los registros de los paquetes enumerados; resulta MUY útil si tiene paquetes de un solo ámbito, es decir, @example-company en diferentes registros (por ejemplo, paquetes npm y GitHub ):


entrada package-lock.json


Ahora, veamos cómo se comporta en términos de velocidad de instalación…

Generar package-lock.json sin caché

Genere package-lock.json e instale dependencias sin caché


Tomó 1 minuto para que npm genere un package-lock.json e instale dependencias sin ningún caché.


Comando utilizado:

 npm i

Instale dependencias desde package-lock.json sin ningún caché

Instale dependencias desde package-lock.json sin ningún caché


Tomó 18 segundos para que npm instale dependencias desde package-lock.json sin ningún caché.


Comando utilizado:

 npm ci

Instalar dependencias desde package-lock.json con caché global

Instale dependencias desde package-lock.json con caché global


Tomó 8 segundos para que npm instale dependencias desde package-lock.json con caché global.


Comando utilizado:

 npm ci

Administrar espacios de trabajo

Pude crear un espacio de trabajo y administrar dependencias para todo el espacio de trabajo a la vez y para proyectos específicos por separado.


En otras palabras, hace el trabajo sin errores ni problemas, y la documentación oficial es bastante sencilla.


Funciones del espacio de trabajo que utilicé hasta ahora:


  1. Instale dependencias para todos los proyectos dentro del espacio de trabajo.
  2. Instalar dependencias para un único proyecto específico.
  3. Ejecute un único script para todos los proyectos a la vez de forma recursiva.

hilo

Sinceramente, no he probado mucho algunas de las funciones del hilo . Quiero decir, lo usé mucho en términos de "instalar dependencias" mientras trabajaba en algunos proyectos, y eso es todo.


Yarn no viene con un instalador de Node.js , por lo que tendrás que instalarlo por separado. Significa que habría un paso adicional en sus canalizaciones de CI : tendría que configurar hilo antes de instalar las dependencias de su proyecto.

Administrar dependencias

Yarn tiene dos enfoques para instalar dependencias:


  1. Instalaciones cero ” (predeterminado): crea una carpeta .yarn y enumera los paquetes en archivos yarn.lock y .pnp.cjs .


  2. Uno normal, similar a npm , almacena las dependencias en node_modules y las enumera en el archivo yarn.lock .


ℹ️ Los archivos de bloqueo de hilo almacenan información sobre los registros de todos los paquetes enumerados SÓLO si utiliza el método de instalación antiguo (normal).


⚠️ Tenga en cuenta que " Zero Installs " parece almacenar paquetes en el caché local y proporcionar enlaces a sus archivos de bloqueo:


Enlaces de paquetes

Puede ser importante para usted si tiene una canalización Dockerfile o CI donde instala dependencias en un entorno limpio y luego desea moverlas a otro (deberá copiar tanto la carpeta .yarn como el caché local).


Dado que el enfoque predeterminado para hilo ahora es " Instalaciones cero " y tiene mejor rendimiento que el enfoque anterior, registraremos puntos de referencia solo con este enfoque.

Generar archivos de bloqueo sin caché

Genere archivos de bloqueo con hilo e instale dependencias.


Tomó 16,5 segundos para que Yarn genere un archivo yarn.lock e instale dependencias sin caché.


Comando utilizado:

 yarn install

Instalar dependencias de archivos de bloqueo existentes sin ningún caché

Instale dependencias con el enfoque "Instalación cero" y sin caché


Tomó 11 segundos para que Yarn instale dependencias con el enfoque de “Instalación cero” y sin ningún caché.


Comando utilizado:

 yarn install --frozen-lockfile

Instalar dependencias de archivos de bloqueo existentes con caché global


Instale dependencias con enfoque de "instalación cero" y caché global


Tomó 8 segundos para que Yarn instale dependencias con el enfoque de “Instalación cero” y caché global.


Comando utilizado:

 yarn install --frozen-lockfile

Administrar espacios de trabajo

Pude crear un espacio de trabajo y administrar dependencias para todos los proyectos a la vez y para proyectos específicos por separado.


Funciones del espacio de trabajo que utilicé hasta ahora:


  1. Instale dependencias para todos los proyectos dentro del espacio de trabajo.
  2. Instalar dependencias para un único proyecto específico.
  3. Ejecute un único script para todos los proyectos a la vez de forma recursiva.


La documentación está bien, pero los nombres de los comandos y las banderas son algo confusos.


Por ejemplo, debo ejecutar esto para ejecutar el script test en la raíz ( . ) y el proyecto b2b anidado:


 yarn workspaces foreach -A --include '{.,b2b}' run test


En comparación con npm :


 npm run test --workspace=b2b --include-workspace-root

pnpm

pnpm actualmente está de moda: muchas empresas y proyectos de código abierto lo utilizan .


Al igual que Yarn , pnpm no viene con un instalador de Node.js , por lo que deberá instalarlo por separado. Significa que habrá un paso adicional en sus canalizaciones de CI : tendrá que configurar pnpm antes de instalar las dependencias de su proyecto.

Administrar dependencias

pnpm se considera un " administrador de paquetes rápido y eficiente en el espacio en disco " ...


De hecho, estoy de acuerdo con la afirmación de "eficiente espacio en disco" en términos de gestión de dependencias localmente.


De forma predeterminada, pnpm elimina las duplicaciones de las dependencias compartidas. pnpm crea enlaces simbólicos para los paquetes que se utilizan en múltiples dependencias. es decir, si los paquetes a y b usan el paquete c como dependencia, pnpm almacenará el paquete c como una copia única y creará enlaces simbólicos para los paquetes a y b . De esa manera, el administrador de paquetes no crea copias impresas y ahorra memoria en su SSD/HDD.


ℹ️ pnpm-lock.yaml no almacena información sobre los registros de los paquetes enumerados.


⚠️ Tenga en cuenta que pnpm a veces almacena dependencias en la caché global, en lugar de mantenerlo como proyecto.

Genere pnpm-lock.yaml sin ningún caché

Generar pnpm-lock.yaml


Tomó 31 segundos para que pnpm genere un pnpm-lock.yaml e instale dependencias sin ningún caché.


Comando utilizado:

 pnpm install

Instalar dependencias desde pnpm-lock.yaml sin caché global

Instale dependencias desde pnpm-lock.yaml sin caché global


Tomó 16 segundos para que pnpm instale dependencias desde pnpm-lock.yaml sin caché.


Comando utilizado:

 pnpm i --frozen-lockfile


Instalar dependencias del archivo de bloqueo existente con caché global

Instalar dependencias desde pnpm-lock-yaml con caché


Tomó 5 segundos para que pnpm instale dependencias desde pnpm-lock.yaml con caché global.


Comando utilizado:

 pnpm i --frozen-lockfile

Administrar espacios de trabajo

Ahora, ahí es donde las cosas se vuelven realmente interesantes...


pnpm tiene muchas opciones de configuración, ¡pero algunas funciones principales simplemente no funcionan!


Repasemos un par de errores que enfrenté:

instalación pnpm --filtro

Es importante poder instalar dependencias solo para proyectos específicos; es bastante útil para monorepos cuando crea canalizaciones relacionadas con proyectos específicos dentro del espacio de trabajo.


es decir, imagina que tienes en tu espacio de trabajo:


  • una aplicación web,
  • servidor de fondo,
  • proyecto de prueba (pruebas de extremo a extremo).


Todos estos son proyectos npm separados, pero son parte del mismo repositorio ☝️


Ahora desea que una canalización ejecute pruebas de un extremo a otro únicamente. Entonces, solo necesitas dependencias de prueba de un extremo a otro, ¿verdad?


Bueno, no podrás hacer eso: ¡pnpm te obliga a instalar dependencias para todo el espacio de trabajo!


Se suponía que pnpm install --filter <project-name> instalaría dependencias solo para proyectos seleccionados, pero no funciona.


Hay un error de hace un año y recientemente se cerró con una solución que no funciona.

instalación recursiva = falso

pnpm instala de forma predeterminada dependencias para todo el espacio de trabajo (todos los proyectos) cuando ejecuta pnpm install


Puede alternar este comportamiento si configura recursive-install=false en .npmrc en la raíz de su espacio de trabajo.


PERO introduce otro error que ya tiene casi 2 años .

espacio de trabajo compartido-lockfile=false

pnpm almacena de forma predeterminada la lista de dependencias en un único archivo de bloqueo (igual que npm y Yarn ).


También puede alternar este comportamiento si configura shared-workspace-lockfile=false en .npmrc en la raíz de su espacio de trabajo.


Eso nos permitiría mantener la función del espacio de trabajo y usar el indicador --ignore-workspace para instalar dependencias para un proyecto específico.


De todos modos, esta configuración introduce un par de problemas más:


  1. eslint y tsc --noEmit arrojan un error "JavaScript sin memoria" en mis canalizaciones de GitHub Actions .


  2. Algunas de las dependencias se almacenan en la caché global y tienen enlaces simbólicos en node_modules/.pnpm .

Resultados de la comparación de rendimiento

#

npm

hilo

pnpm

Generar un archivo de bloqueo

60 seg

16,5 segundos

31 seg

Instalar dependencias sin caché

18 seg

11 seg

8 seg

Instalar dependencias con caché global

8 seg

8 seg

5 segundos


Según el punto de referencia anterior, npm es el administrador de paquetes más lento ☝️


De todos modos, interpretemos estos resultados…

Generar un archivo de bloqueo

Es un caso raro. Por lo general, se crea un archivo de bloqueo al inicializar el proyecto y luego se expande cuando instala/actualiza paquetes.


Teniendo esto en cuenta, no parece algo muy importante en lo que confiar al elegir un administrador de paquetes.

Instalar dependencias

En la mayoría de los casos, sus proyectos mantienen una lista específica de dependencias y rara vez agrega o elimina algo.


Lo más probable es que cambies las versiones de tus paquetes de vez en cuando; estos cambios son pequeños y reutilizarás el resto de los paquetes del caché.


En otras palabras, el caso de uso común es: buscar nuevos paquetes del registro de paquetes y tomar el resto del caché.


pnpm (5-8 segundos) es casi el doble de rápido que npm (8-18 segundos) con hilo (8-11 segundos) en el medio.

Conclusión

Hechos

  • pnpm es de hecho un administrador de paquetes “rápido y eficiente en disco” ; ¡está bastante claro en la revisión actual!


  • La característica del espacio de trabajo pnpm tiene errores y algunos de los errores no se han resuelto durante años.


  • Tanto pnpm como Yarn requieren una configuración adicional en las canalizaciones de CI, mientras que npm no.


  • Tanto pnpm como Yarn no almacenan información de registro de paquetes en sus archivos de bloqueo, mientras que npm sí.

Pensamientos del autor

Creo que pnpm hace el mejor trabajo si su requisito para el administrador de paquetes es tan simple como "instalar solo dependencias".


Aunque pnpm no viene con un instalador de Node.js listo para usar, es fácil de configurar en canalizaciones de CI con corepack o action existente .


Prefiero npm porque:


  • es estable (especialmente espacios de trabajo),


  • viene con Node.js y no requiere una configuración adicional en el proceso de CI,


  • almacena registros de paquetes en package-lock.json para que pueda instalar dependencias con un único alcance desde diferentes registros.


Estas ventajas superan los segundos de velocidad y espacio en disco que ahorraría con hilo o pnpm .


¿Cuáles son sus criterios para elegir un administrador de paquetes? ¡No seas tímido y déjame saber tu opinión en la sección de comentarios a continuación! 👇😊