Circular Dependencies in NodeJS

Avoid what I will name “Circular dependencies”

Circular dependencies occur when two or more modules reference each other. The more references you make inside your code, the harder it is to test and more complicated to understand, and sometime it creates nasty issues.

Some may split into two different types:

  • Direct - For example, class A needs class B, and class B also needs class A
  • Indirect - For example, class A needs class B, class B also needs class C, and class C needs class A

Examples to avoid:

import { ServiceB } from './ServiceB';

export class ServiceA {
  ...
}
...
import { ServiceA } from './ServiceA';

export class ServiceB {
  ...
}
import { ServiceB } from './ServiceB';

export class ServiceA {
  ...
}
...
import { ServiceC } from './ServiceC';

export class ServiceB {
  ...
}
...
import { ServiceA } from './ServiceC';

export class ServiceC {
  ...
}

Use package named ‘madge’ to check DI

One tool to consider for checking your circular dependencies is to use madge. This tool is pretty handy when i comes to detect circular dependencies, also displays the view in a nice view.

Add dependency to your development dependencies

npm i -D madge

Add a script for checking the dependencies, and script to check the circular ones:

{
  ...
  "scripts": {
    ...
    "dependencies": 
      "madge --extensions js,ts src",
    "circular:dependencies": 
      "madge --circular --extensions js,ts src",
  }
}

Or if you want a visualization part as svg which requires Graphviz in you machine you can add the following scripts:

{
  ...
  "scripts": {
    ...
    "dep:svg": 
      "madge --image dep.svg --extensions js,ts src",
    "circular:dep:svg": 
      "madge --circular --image cir.svg src",
  }
}

Keep pushing forward and savor every step of your coding journey.