Babel: Certain ES6 import/export patterns cause undefined imports (T7113)

Created on 16 Feb 2016  路  3Comments  路  Source: babel/babel

Issue originally made by @TMiguelT

Bug information

  • Babel version: 6.5.2
  • Node version: 2.0.1
  • npm version: 2.9.0

    Options

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.

Description

outdated

Most helpful comment

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.

All 3 comments

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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Tin-Nguyen picture Tin-Nguyen  路  3Comments

mathiasbynens picture mathiasbynens  路  3Comments

nicolo-ribaudo picture nicolo-ribaudo  路  3Comments

alloy picture alloy  路  3Comments

jdalton picture jdalton  路  3Comments