es

Monorepos

Comparte dependencias entre muchos proyectos en un solo repositorio, con un lockfile y un store.

Si tienes un monorepo de .NET (un repo, muchos .csproj, una solución o muchas), PCPM lo trata como un workspace: un pcpm.lock, un store y un Directory.Packages.props para todo el árbol.

Esta página cubre el lado práctico: cómo disponer tu repo para que PCPM lo vea, y qué esperar de pcpm install a escala de monorepo.

Layout recomendado

A PCPM no le importa el layout, pero la siguiente es una convención que funciona bien:

monorepo/
├── pcpm-workspace.yaml          # globs de proyectos
├── Directory.Packages.props     # manifiesto de versiones central
├── pcpm.json                    # config del workspace
├── pcpm.lock                    # generado por pcpm install
├── apps/
│   ├── web/                     # proyecto ASP.NET
│   │   └── web.csproj
│   └── worker/                  # worker en background
│       └── worker.csproj
├── libs/
│   ├── shared/                  # librería interna
│   │   └── shared.csproj
│   └── contracts/
│       └── contracts.csproj
└── tools/
    └── migrations/
        └── migrations.csproj

El pcpm-workspace.yaml que le corresponde:

packages:
  - "apps/*"
  - "libs/*"
  - "tools/*"

Cada .csproj bajo apps/, libs/ y tools/ es parte del workspace. El lockfile los cubre todos.

Añadir una dependencia

Por defecto, pcpm add escribe el <PackageReference /> en todos los proyectos del workspace. Si solo quieres uno:

pcpm add Serilog --project apps/web/web.csproj

Si quieres un subconjunto:

pcpm add Microsoft.Extensions.Hosting \
  --project apps/web/web.csproj \
  --project apps/worker/worker.csproj

Versionado

Central Package Management te da un único lugar para fijar versiones:

<Project>
  <PropertyGroup>
    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
  </PropertyGroup>
  <ItemGroup>
    <PackageVersion Include="Serilog" Version="3.1.1" />
    <PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
  </ItemGroup>
</Project>

PCPM escribe estas entradas <PackageVersion /> por ti. El <PackageReference /> en cada .csproj referencia el mismo id sin versión:

<ItemGroup>
  <PackageReference Include="Serilog" />
</ItemGroup>

Resolución transitiva

Un monorepo con N proyectos tiene un único grafo de dependencias. PCPM lo resuelve como un todo, lo que significa:

  • Un paquete requerido por dos proyectos se descarga una sola vez.
  • Los conflictos se resuelven globalmente — solo hay una versión de Newtonsoft.Json en disco, aunque apps/web y libs/contracts pidan rangos distintos.
  • pcpm.lock contiene cada dependencia directa y transitiva, así que cualquier re-ejecución (CI, nuevo dev, build Docker) produce la misma restauración.

Compartir proyectos internos

Los proyectos dentro de un monorepo se referencian entre sí con <ProjectReference /> normales. PCPM no necesita saber de ellos — ve el grafo de .csproj resuelto y simplemente resuelve las dependencias de NuGet.

Si quieres forzar a que todos los proyectos usen la misma versión de una librería interna, usa un <PackageVersion /> en Directory.Packages.props y referencia el proyecto solo por id.

Cuando el monorepo crece

En un monorepo con cientos de proyectos, el lockfile puede ser grande (piensa en decenas de miles de entradas transitivas). PCPM lo maneja — la resolución es O(V + E) en el peor caso, con caché que hace las re-ejecuciones esencialmente gratuitas — pero el diff del lockfile puede ser ruidoso.

Consejos prácticos:

  • Usa pcpm outdated y pcpm update <pkg> para mantener los bumps de versión intencionales. Evita que cada ejecución de CI resuelva contra un rango amplio.
  • Mantén pcpm-workspace.yaml estrecho. Cuanto más amplios los globs, más grande el lockfile, y más lento se vuelve pcpm list (imprime el grafo entero).
  • Si tienes rodajas verdaderamente independientes (p. ej. móvil + backend en el mismo repo), considera múltiples workspaces — un pcpm-workspace.yaml por rodaja, cada uno con su propio lockfile.

Cuándo no usar un monorepo

PCPM se siente cómodo corriendo contra un único .sln con dos .csproj. No necesitas un pcpm-workspace.yaml para eso. Recurre a la configuración de monorepo cuando tu repo tiene 10+ proyectos, o cuando quieres un lockfile compartido entre múltiples soluciones.