Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Webpack import returns undefined, depending on the order of imports

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?

like image 384
Alec Mev Avatar asked Feb 06 '16 11:02

Alec Mev


Video Answer


2 Answers

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 module C, which, in turn, imports B. A gets imported first in main.js, so B 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 returning A's module.exports, which is still undefined. Eventually, it becomes equal to some-const, but the synchronous code in B ends up dealing with undefined instead.

Eliminating the circular dependency, by moving out the code that C depends on out of B, 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].

like image 141
Alec Mev Avatar answered Sep 19 '22 13:09

Alec Mev


This plugin(pointed above) solved the issue for me as well.

I recommend setting this flag to avoid adding additional circular dependencies in the future.

// add errors to webpack instead of warnings failOnError: true 

There is also a eslint plugin to address it.

like image 29
Raz Avatar answered Sep 17 '22 13:09

Raz