I'm using webpack + babel. I have three modules looking like this:
// A.js
// some other imports here
console.log('A');
export default 'some-const';
// B.js
import someConst from './A';
console.log('B', someConst);
export default 'something-else';
// main.js
import someConst from './A';
import somethingElse from './B';
console.log('main', someConst);
When main.js
is executed, I see the following:
B undefined
A
main some-const
If I swap the imports in main.js
, B
becoming the first, I get:
A
B some-const
main some-const
How come B.js
gets undefined
instead of a module in the first version? What's wrong?
After almost a full workday of narrowing down the issue (AKA hair-pulling), I've finally came to realize that I have a circular dependency.
Where it says
// some other imports here
,A
imports another moduleC
, which, in turn, importsB
.A
gets imported first inmain.js
, soB
ends up being the last link in the "circle", and Webpack (or any CommonJS-like environment, for that matter, like Node) just short-circuits it by returningA
'smodule.exports
, which is stillundefined
. Eventually, it becomes equal tosome-const
, but the synchronous code inB
ends up dealing withundefined
instead.Eliminating the circular dependency, by moving out the code that
C
depends on out ofB
, has resolved the issue. Wish Webpack would somehow warn me about this.Edit: On the last note, as pointed out by @cookie, there's a plugin for circular dependency detection, if you'd like to avoid hitting this problem [again].