Modifying ES6 module exports

Caridy Patino caridy at gmail.com
Wed Dec 23 01:49:56 UTC 2015


circular dependencies will work nicely with declarations, not so much with expressions because the code has to be evaluated to set those bindings. This, of course, is not a problem if you're not invoking some initialization when evaluating the body of the module.

all in all, that's what you're experiencing. as for the {}, that's just babel. 

side note: this has nothing to do with those being default exports, it will happen for any export.

/caridy

> On Dec 21, 2015, at 10:25 PM, /#!/JoePea <joe at trusktr.io> wrote:
> 
> I'm curious, what should happen when module A imports the default from
> module B which imports the default from module A? Should the exported
> A object exist inside of module B?
> 
> Here's two modules A and B (simplified from some real code that I
> have), which have a circular dependency:
> 
> ```js
> // A.js
> import B from './B'
> let A = window.globalThing
> export default A
> 
> // modify the A object adding methods that reference B.
> ```
> 
> ```js
> // B.js
> import A from './A'
> let B = new window.OtherThing
> export default B
> 
> console.log(A) // an empty object, {}
> 
> // modify the B object which depends on A existing (not being some temporary
> // object like I get with Webpack) while the module is evaluated.
> ```
> 
> When using Webpack, this code fails because the reference to A in B is
> some empty object. If I import both A and B into main.js, then A is
> defined as epected:
> 
> ```js
> // main.js
> import A from './A'
> import B from './B'
> 
> console.log(A) // An object with a bunch of properties, as expected.
> ```
> 
> I can fix my problem by exporting functions to do setup of A and B,
> and running those functions in main.js, like this:
> 
> ```js
> // A.js
> import B from './B'
> let A = window.globalThing
> export default A
> 
> A.setup = () => {
>  // modify the A object adding methods that reference B.
> }
> ```
> 
> ```js
> // B.js
> import A from './A'
> let B = new window.OtherThing
> export default B
> 
> console.log(A) // an empty object, {}
> 
> B.setup = () => {
>  console.log(A) // the expected object!! Why?
> 
>  // modify the B object which depends on A existing (not being some temporary
>  // object like I get with Webpack) while the module is evaluated.
> }
> ```
> 
> When using Webpack, this code fails because the reference to A in B is
> just `{}`, some empty object. If I import both A and B into main.js,
> then A is defined as epected:
> 
> ```js
> // main.js
> import A from './A'
> import B from './B'
> 
> A.setup()
> B.setup()
> 
> // no more problems!
> 
> console.log(A) // An object with a bunch of properties, as expected.
> ```
> 
> So, if I run the setup for A and B in main.js instead of in the module
> evaluation, everything works perfectly.
> 
> This led me to wonder: What is the expected behavior of circular
> dependencies in ES2015? Have you had this 'empty object' problem
> before? Is that expected to happen, or might there be a bug in
> Webpack?
> 
> I guess the problem makes sense: How can the first method (running
> relying on module evaluation for setting up A and B exports) work if
> module B depends on the evaluation of module A which depends on the
> evaluation of module B?
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss


More information about the es-discuss mailing list