ADR 004: pnpm como gestor de paquetes

Estado: Aceptado Fecha: 2025-03-15 Ultima actualizacion: 2026-02-26

Contexto

Necesitamos un gestor de paquetes tanto para el monorepo como para los polyrepos de MFE. Debe soportar workspaces, ser rapido y gestionar correctamente las complejidades de las dependencias compartidas de Module Federation.

Decision

Usar pnpm 10.30.3 en todos los repositorios. Fijar la version via Corepack ("packageManager": "pnpm@10.30.3" en el package.json raiz).

Notas de migracion a pnpm 10

pnpm 10 introduce varios breaking changes respecto a pnpm 9.x que deben abordarse:

Scripts de ciclo de vida deshabilitados por defecto

En pnpm 10, los scripts de ciclo de vida pre/post (p.ej., preinstall, postinstall, prepare) ya no se ejecutan por defecto. Para restaurar el comportamiento anterior:

  • Agregar enable-pre-post-scripts=true al .npmrc en la raiz de cada repositorio, o
  • Usar la lista de permitidos onlyBuiltDependencies en package.json para autorizar explicitamente que paquetes especificos ejecuten scripts de instalacion (recomendado por seguridad).

Cambios en el hoisting

pnpm 10 modifica el comportamiento de hoisting por defecto. Los valores predeterminados de public-hoist-pattern se han restringido. Para las dependencias compartidas de Module Federation, asegurar que .npmrc configure explicitamente:

public-hoist-pattern[]=*types*
public-hoist-pattern[]=*eslint*
public-hoist-pattern[]=react
public-hoist-pattern[]=react-dom

Otras consideraciones de migracion a pnpm 10

  • El valor por defecto de resolution-mode cambio a highest en pnpm 10. Si dependias de lowest-direct, configuralo explicitamente en .npmrc.
  • El formato de pnpm-lock.yaml se ha actualizado (lockfile v9). El primer pnpm install tras la actualizacion migrara el lockfile automaticamente. Hacer commit del lockfile actualizado.
  • El comportamiento del flag --filter se ha endurecido; verificar que los scripts de filtro de workspace sigan funcionando tras la actualizacion.
  • Node.js 18 es la version minima requerida para pnpm 10.
Tarjeta de decision de pnpm 10.30.3 pnpm 10.30.3 Positivo Almacenamiento content-addressable Aislamiento estricto de deps Protocolo workspace:* Instalaciones rapidas Negativo Problemas con node_modules estricto Requiere config en .npmrc Scripts de ciclo de vida deshabilitados

Consecuencias

Positivas

  • Almacenamiento content-addressable: los paquetes se almacenan una sola vez en disco, enlazados con hard links en node_modules (ahorro significativo de espacio en disco)
  • Aislamiento estricto de dependencias por defecto (no se pueden usar accidentalmente dependencias no declaradas)
  • Soporte nativo de workspaces con protocolo workspace:*
  • Instalaciones mas rapidas que npm/yarn en la mayoria de benchmarks
  • pnpm-lock.yaml es determinista y mas facil de revisar que package-lock.json
  • Soporte integrado para overrides de .npmrc por workspace
  • Compatible con Corepack para fijar la version (pnpm 10.30.3)

Negativas

  • La estructura estricta de node_modules puede causar problemas con herramientas que esperan hoisting plano (dependencias compartidas de Module Federation, algunos paquetes legacy)
  • Requiere configuracion de .npmrc para que public-hoist-pattern funcione con dependencias compartidas de MF
  • Comunidad mas reducida que npm (aunque crece rapidamente)
  • Algunos entornos de CI no traen pnpm preinstalado (necesitan corepack enable o pnpm/action-setup)
  • pnpm 10 deshabilita los scripts de ciclo de vida por defecto, requiriendo configuracion explicita de .npmrc o la lista de permitidos onlyBuiltDependencies

Alternativas consideradas

  • npm: Ubicuo pero lento, node_modules plano causa phantom dependencies, soporte de workspaces menos maduro. Sin almacenamiento content-addressable.
  • yarn (v3/v4 con PnP): Plug'n'Play es innovador pero causa problemas de compatibilidad con muchas herramientas (especialmente Module Federation, que espera node_modules). Berry (v3+) tiene una curva de aprendizaje pronunciada. Classic yarn (v1) esta en modo de mantenimiento.
  • yarn (v1 classic): Maduro y estable pero ya no se desarrolla activamente. Sin almacenamiento content-addressable, sin aislamiento estricto de dependencias.
  • Bun: Rapido pero aun madurando, no todas las APIs de Node.js soportadas en contexto de Workers, soporte de workspaces aun en evolucion.