Issue originally made by @TMiguelT
Bug information
The issue in question can be seen by cloning the repo here https://github.com/TMiguelT/babel-export-issue and then running `npm start` or `node index.js`. The repo includes a pre-build js file, but if you want to test that Babel is producing this output, feel free to run `npm build` to cause a rebuild.
Comment originally made by @loganfsmyth
That is to be expected, you have a circular dependency in your files
entry.js -> actions.js -> store.js -> actions.js
When store.js
loads action.js
, it is already in the queue, but hasn't executed yet because it is waiting for store.js
to finish. Now because store.js
depends on actions.js
, but it is already loading, it will run store.js
. The imported value actionTypes
is undefined because actions.js
hasn't executed yet.
In a real ES6 environment, this would throw a temporal deadzone error, but Babel does not support them in this case.
Your best bet would be to instead make store.js
be:
export {actionTypes as default} from './actions';
so that the value is re-exported directly. This will take advantage of live bindings and avoids actually accessing the value of actionTypes
until after actions
has executed.
Comment originally made by @TMiguelT
Okay I can see the circular dependency and can probably refactor that out of my code.
However for the sake of Babel, shouldn't a circular dependency cause an error in the actual compilation, or at least make the exported value (actionTypes in my case) throw an Error when accessed (for example using an ES5 getter that throws). I didn't really think about the fact that this was a circular dependency and I was very confused why I was getting an undefined value, and I suspect other people might encounter this problem. Is there no way of alerting the users when they do this?
In a real ES6 environment, this would throw a temporal deadzone error, but Babel does not support them in this case.
Maybe we can if we operated on more than one file at a time or if we added a run-time check. Otherwise I would look to a bundler like webpack or https://github.com/benmosher/eslint-plugin-import which might help with this
Most helpful comment
That is to be expected, you have a circular dependency in your files
When
store.js
loadsaction.js
, it is already in the queue, but hasn't executed yet because it is waiting forstore.js
to finish. Now becausestore.js
depends onactions.js
, but it is already loading, it will runstore.js
. The imported valueactionTypes
is undefined becauseactions.js
hasn't executed yet.In a real ES6 environment, this would throw a temporal deadzone error, but Babel does not support them in this case.
Your best bet would be to instead make
store.js
be:so that the value is re-exported directly. This will take advantage of live bindings and avoids actually accessing the value of
actionTypes
until afteractions
has executed.