DEV Community

Cover image for Tired of circular dependency in Typescript/Node.js?
Tahsin
Tahsin

Posted on

Tired of circular dependency in Typescript/Node.js?

First of all, let’s see what is a circular dependency. According to this Wikipedia:

In software engineering, a circular dependency is a relation between two or more modules which either directly or indirectly depend on each other to function properly. Such modules are also known as mutually recursive.

Circular dependency demonstration

Alright, what does it mean? Well, to understand it properly let’s clone this repository and cd into src/good dir & inspect the files.

What we can see there is, a.ts is importing a variable from b.ts & in the main.ts we are importing & printing the variable from a.ts. So the flow looks like this:

Circular depndency possibilities

When we execute main.ts by npx ts-node main.ts here is the output:

Working fine without circular depndency

So far so good. Now let’s cd into src/problem dir & inspect what's going on. Here we can see a.ts importing a variable from b.ts and so does b.ts the opposite. And in main.ts it’s importing a variable from a.ts & b.ts and printing them. In this case, the flow looks like this:

Circular depndency

When we execute main.ts by npx ts-node main.ts here is the output:

Module not loaded correct because of circular dep

What is going on? In the last line instead of John, we are seeing undefined. Didn’t we import the variable correctly? Yes, we did. But it is happening because of the circular dependency problem. Look at the problem dir flow above. File a.ts is dependent on b.ts & b.ts dependent on a.ts.

How it’s happening let’s talk about it another time, but before that let’s see how we can detect it.

In a small program like this, it’s not a big problem to detect circular dependency. But in a large codebase, once we depend on a wrong module accidentally, then it’s tough to detect this later on. So today we are gonna use a tool call madge. Let’s see how we are gonna use it.

cd into src/good dir & execute npx madge --extensions js,ts --circular .

What do you see? No problems found. Right? Yeah. Because there is no circular dependency problem.

No circular dependency

Now cd into src/problem dir & execute npx madge --extensions js,ts --circular .

What do you see? It’s awesome, right? The way it shows which files are circularly depending on what files, in a large codebase, it saves a lot of time.

Circular dependency detected

Oiya, before we forget, of course in a large codebase we use tsconfig.json. If we have module aliases or something like that, we have to point to that tsconfig.json. So in that case we can add another flag like this:

Command with TypeScript

If we do not use typescript, we don’t have to use --ts-config flag as well as ts in the --extensions flag.

Alright, enough for today. Next, hopefully, we will talk about how circular-dependency gets created underneath. Thank You.

Happy Coding 💻

Discussion (0)