Tags y constraints en monorepos con Nx

Resumen

Si trabajas con un monorepo en Nx y quieres mantener una arquitectura limpia, los tags y las constraints son tu mejor aliado. Te permiten clasificar cada proyecto por capa o función y, lo más importante, evitar que tu código termine en un nudo de dependencias circulares que después nadie quiere desenredar.

Qué son los tags en Nx y para qué sirven

Los tags en Nx son etiquetas que asignas a cada proyecto del monorepo, ya sea una aplicación o una biblioteca, para clasificarlo según su función. Con ellos puedes definir reglas de dependencia y asegurar que cada proyecto cumpla un rol puntual dentro de la arquitectura.

¿Qué es un tag en Nx? Es una etiqueta que defines en el project.json de cada proyecto para identificar su capa o scope, por ejemplo scope:app, scope:ui, scope:api o scope:utils.

La idea es simple: si un proyecto tiene una etiqueta clara, puedes decirle a Nx con quién puede o no puede relacionarse.

Cómo asigno tags a cada proyecto del monorepo

El proceso pasa por entrar a la carpeta packages y editar el project.json de cada proyecto. Ahí defines el tag correspondiente según el rol que cumple.

  • App 1 y App 2: ambas reciben el tag scope:app porque son aplicaciones.
  • Server: se le agrega scope:api debajo del prototype tag.
  • UI shared: lleva scope:ui por ser una librería de interfaz.
  • Utils common: queda como scope:utils, pensada para utilidades.

Con esto cada proyecto ya está taggeado y listo para que Nx pueda aplicar reglas sobre ellos.

Cómo defino constraints en nx.json para controlar dependencias

Una vez asignados los tags, vas al archivo nx.json y agregas la sección de proyectos debajo de Nx Angular y por encima de plugins. Ahí declaras las constraints, que son las limitaciones de dependencia entre capas.

Las reglas quedan así:

  • utils: solo puede depender de utils.
  • ui: puede depender de utils y de ui.
  • api: solo puede depender de utils.
  • app: puede depender de utils, ui y api.

Esta jerarquía es la que evita que, por ejemplo, una librería de utilidades termine importando algo de la API o que la UI dependa de la capa de servidor. El control queda en manos del linter, que al ejecutarse revisa que ninguna de estas reglas se rompa.

¿Por qué necesito constraints en un monorepo? Porque sin ellas cualquier proyecto puede importar a cualquier otro, y eso lleva a dependencias circulares y a una arquitectura imposible de mantener.

Cómo replico la configuración en ESLint

La misma lógica de constraints se repite en la configuración de ESLint, dentro de la sección de source tag. La estructura es muy similar a la de nx.json:

  • scope:utils solo depende de utils.
  • scope:ui depende de utils y ui.
  • scope:api depende solo de utils.
  • scope:app depende de utils, ui y api.

Así queda la configuración general de ESLint alineada con las reglas del monorepo.

Cómo verifico que las restricciones funcionan correctamente

Después de configurar todo, ejecutas el linter como lo venías haciendo antes. Si los tres proyectos pasan sin errores, significa que no hay dependencias circulares ni reglas rotas.

¿Qué pasa si rompo una constraint en Nx? El linter detecta la violación y falla la verificación, avisándote antes de que el código entre al repositorio.

Y aquí viene lo interesante: con esta configuración tu arquitectura queda blindada. Ya no depende de la disciplina del equipo, depende de una regla automatizada que se ejecuta cada vez que pasas el linter.

Qué logras al taggear todos los proyectos

Al tener cada aplicación y librería taggeada, agregada al nx.json y reflejada en la configuración de ESLint, consigues varias cosas a la vez:

  1. Una clasificación clara por capas (app, ui, api, utils).
  2. Reglas explícitas sobre quién puede depender de quién.
  3. Validación automática vía linter en cada ejecución.
  4. Una arquitectura prolija que previene dependencias circulares.

Con los tests unitarios, los linters y los tags configurados, tu monorepo trabaja con una estructura sólida que se sostiene sola. ¿Ya estás usando tags en tus proyectos Nx? Cuéntame en los comentarios cómo organizas los scopes en tu equipo.