Wiedii — Política de Monorepo con Nx
Usar Nx cuando el proyecto tiene múltiples paquetes que comparten código o se despliegan de forma independiente.
Cuándo usar un monorepo
- Múltiples apps o paquetes que comparten código común
- Necesidad de despliegue independiente por paquete
- Equipos trabajando en componentes separados pero relacionados
Comandos clave
bun nx affected -t build # compilar solo los paquetes afectados
bun nx affected -t test # testear solo los paquetes afectados
bun nx run-many -t lint # linting en todos los paquetes
bun nx graph # visualizar el grafo de dependencias
nx.json
{
"targetDefaults": {
"build": { "dependsOn": ["^build"], "cache": true },
"test": { "cache": true },
"lint": { "cache": true }
},
"defaultBase": "develop"
}
defaultBase: "develop" se alinea con Git Flow — los afectados se calculan comparando contra develop.
⚠️ "type": "module" NO va en el package.json raíz del workspace
A diferencia de un repo de un solo paquete (donde el template de mise-tooling sí incluye "type": "module"), el package.json de la raíz de un monorepo Nx NO debe declarar "type": "module".
Por qué: Nx y sus plugins (@nx/js, @nx/rollup, etc.) generan y cargan archivos de configuración .js asumiendo CommonJS. Con "type": "module" en la raíz, todo .js pasa a interpretarse como ESM y los generators (nx g), las migraciones (nx migrate) y ciertos executors pueden romper con errores tipo module is not defined o require is not defined. Aunque build/lint/test puedan pasar en un momento dado, es frágil: el primer nx g @nx/js:library que emita un .js CommonJS rompe.
Patrón correcto:
| Ubicación | "type": "module" |
|---|---|
package.json raíz del workspace | ❌ No declararlo |
package.json de cada paquete en packages/* | ✅ Sí (son librerías ESM) |
Archivos de config en la raíz que necesitan ser ESM: usar extensión .mjs explícita en lugar de depender de "type": "module":
eslint.config.mjs,eslint.base.config.mjs→.mjscommitlint.config.mjs→.mjs(el hookcommit-msgde wiedii-configs auto-detecta.js/.cjs/.mjs)changelog.config.mjs→.mjs- Configs de Nx que deban ser CommonJS →
.cjs(ej.rollup.config.cjs, que@nx/rollupgenera así por defecto)
En resumen: en un monorepo Nx, el tipo de módulo se decide por extensión de archivo (
.mjs/.cjs), no con"type": "module"en la raíz. Cada paquete publicable sí lo lleva.
Aplicación de políticas en monorepo
| Política | Aplicación en monorepo |
|---|---|
| Git Flow | Una instancia por monorepo |
mise.toml | En la raíz del monorepo |
lefthook.yaml | En la raíz — los hooks aplican a todos los paquetes |
| Linters | Config compartida en la raíz, override por paquete si es necesario |
| Quality gates de CI | nx affected -t lint,test,build en lugar de run-all |