Modifying ES6 module exports

Logan Smyth loganfsmyth at gmail.com
Tue Dec 22 04:05:42 UTC 2015


To start, an object is definitely not what I'd expect. The core thing to
remember with ES6 modules is that while imports are live bindings, you
still need to write your code in such a way that it has no run-time
circular dependencies.

In your specific examples, you are importing `A` first, which will begin
`B` loading. Since `A` has not finished executing yet, and B will be
attempting to access the the `A` import before the `A.js` file has begin
executing. I'm not 100% sure off the top of my head, but in a real ES6
environment, that would either result in the `A` import being `undefined`,
or attempting to access it would throw a temporal dead zone error due to
you accessing a variable before it has been initialized.

If your `A.js` file comment "// modify the A object adding methods that
reference B." adds those references without actually accessing `B` in any
way, then the solution to your issue (in a real environment anyway) would
be to import `B.js` _first_ so that you do not have circular
initialization-time dependencies.

In this case, are you using Babel's ES6 module syntax transpiling, or
Webpack with another transpiler?


On Mon, Dec 21, 2015 at 7: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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20151221/9f74e5ce/attachment.html>


More information about the es-discuss mailing list