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.
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:
When we execute main.ts by npx ts-node main.ts here is the output:
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:
When we execute main.ts by npx ts-node main.ts here is the output:
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.
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.
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:
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 💻
Top comments (0)