Tener dependencias circulares en un proyecto nunca es bueno dado que pueden aparecer efectos negativos que nadie desea.

Veamos un ejemplo muy sencillo de dependencia circular: Tenemos dos archivos que se referencian mutuamente importanto alguno de sus métodos:

Archivo «position.ts» (referencia a positionPlusOne):

import { positionPlusOne } from './positionPlusOne';

export function position(n: number): number {
  if (n < 0) {
    return positionPlusOne(n);
  }
  return n;
}

Archivo «positionPlusOne.ts» (referencia a position):

import { position} from 'position';

export function positionPlusOne(n: number): number {
  return position(n + 1);
}

Al compilar los archivos typescript («tsc position.ts» ó «tsc positionPlusOne.ts») no produce ningún error, incluso si los dos métodos están dentro de un mismo archivo. El caso es que dependiendo de la condición final que se programe puede generarse incluso un bucle infinito entre llamadas mútuas y esto no es nada bueno porque se llenaría la pila de llamadas hasta que se lanzase el típico «stack overflow».

Es aquí donde madge nos ayuda a identificar las dependencias circulares entre módulos, en este caso, vamos a centrarnos en los de typescript (aunque también lo detecta para javascript).

Instalación de madge:

npm install -g madge

De esta manera es accesible de forma global, y bastaría con ejecutarlo de la siguiente manera:

madge --circular --extensions ts .

Ejecutándolo obtendríamos un resultado parecido al siguiente:

madge dependencia circular encontrada
Resultado de madge con dependencia circular

Si por el contrario no deseamos instalarlo de forma global podemos hacerlo de la siguiente manera:

npx -y madge --circular --extensions ts .

Finalmente ya solo quedaría solucionar por nuestra parte esta dependencia circular y volver a ejecutar madge.

Más que dependencias circulares

El paquete madge no solo ofrece el buscar dependencias circulares, ofrece mucho más como:

  • Buscar módulos que dependan de otro
  • Buscar módulos que no dependan de nadie (huérfanos)
  • Buscar módulos que no tengan dependencias
  • Generar una imagen con el grafo de dependencias (requiere instalación de Graphviz)