I am trying to reorganize the import/export statements of my TypeScript React project to make them shorter and cleaner, basically by the approach of defining an index.ts
file in each feature specific folder to export resources (interface/type/function etc.) of that feature. This Smarter way to organize "imports" blog explains almost the same idea.
But suddenly jest execution breaks with below stack trace after the changes. The entities involved have been spoofed for confidentiality purpose.
Test suite failed to run
TypeError: Cannot read property 'FooBarEnum' of undefined
at Object.FooBarEnum (src/features/Zoo/index.ts:93:23)
at Object.<anonymous> (src/features/CarPark/CarParkManager.ts:18:4)
at Object.<anonymous> (src/features/CarPark/index.ts:1:1)
at Object.<anonymous> (src/features/Zoo/ZooManager.ts:1:1)
at Object.<anonymous> (src/features/Zoo/index.ts:14:1)
at Object.<anonymous> (src/features/Rabbit/Rabbit.ts:4:1)
at Object.<anonymous> (test/features/Rabbit/Rabbit.test.ts:2:1)
Basically there is an enum defined in a constant file which can't be read at all.
I am pretty sure my jest setup is correct because it was executing successfully before this. And I use babel-jest
and @babel/preset-typescript
to compile.
Appreciate if someone can point me to a path for debugging as the stack trace doesn't really tell much.
Finally I realized this is caused by a hidden circular dependency in my code base.
[TL;DR] Dependency cycle: Rabbit
> Zoo
index > CarPark
index > Zoo
index.
[Details] The situation is that ZooManager
is exported from the index file of Zoo
folder, and ZooManager
imports CarParkManager
which is exported from the index file of CarPark
folder. 'FooBarEnum' is exported from the index file of Zoo
folder and is used by CarParkManager
, and that constitutes the dependency cycle.
I know the given spoofed example isn't really nice to read upon but this provides a hint that when you encounter similar issues, keep an eye on circular dependencies.
The import/no-cycle ESLint rule can be added to carry out a static check.
And the madge developer tool can be used to construct a visual module dependency graph.
References: