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.Jsonen disco, aunqueapps/webylibs/contractspidan rangos distintos. pcpm.lockcontiene 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 outdatedypcpm 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.yamlestrecho. Cuanto más amplios los globs, más grande el lockfile, y más lento se vuelvepcpm 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.yamlpor 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.