Saltar al contenido principal

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 workspaceNo 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.mjs
  • commitlint.config.mjs.mjs (el hook commit-msg de 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/rollup genera 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íticaAplicación en monorepo
Git FlowUna instancia por monorepo
mise.tomlEn la raíz del monorepo
lefthook.yamlEn la raíz — los hooks aplican a todos los paquetes
LintersConfig compartida en la raíz, override por paquete si es necesario
Quality gates de CInx affected -t lint,test,build en lugar de run-all