When I try this same code with Webpack, I get the *exact same results*: the `console.log` statements in the exact same order, where the last output shows that `A` in the entry point is `undefined`).
Am I misunderstanding something about live bindings? Is there some guaranteed order in which these modules should be evaluated? The reason why I'm after a solution for the circular dependency is because in my real-world case I need to use `instanceof A` and `intanceof B` within the `C` superclass defined in module C. This is a case of the Fragile Base Class Problem where a class should usually *not* have knowledge of it's subclasses, but the base class in my case is intended to be internal only, not a part of the public API that end users will extend from. */#!/*JoePea On Tue, Aug 9, 2016 at 11:12 PM, /#!/JoePea <[email protected]> wrote: > I can get the whole thing to work if I pass the C dependency into the > `setUpA` and `setUpB` functions as follows, but oddly `A` is `undefined` in > the Entrypoint module at the `console.log` statement, which makes it seem > to me like live bindings aren't working the I was expecting. > > ```js > // --- Entrypoint > > import A from './app/A' > console.log('Entrypoint', A) // HERE, output: "Entrypoint undefined" > ``` > > ```js > // --- Module A > > import C from './C' > > let A > > export > function setUpA(C) { > > console.log('setUpA') > console.log(C) > > A = class A extends C { > // ... > } > > } > > console.log('Module A', C, setUpA) > > export {A as default} > ``` > > ```js > // --- Module B > > import C from './C' > > let B > > export > function setUpB(C) { > > console.log('setUpB', C) > > B = class B extends C { > // ... > } > > } > > console.log('Module B', C, setUpB) > > export {B as default} > ``` > > ```js > // --- Module C > > import A, {setUpA} from './A' > import B, {setUpB} from './B' > > let C = class C { > constructor() { > // this may run later, after all three modules are evaluated, or > // possibly never. > console.log(A) > console.log(B) > } > } > > setUpA(C) > console.log('Module C', A) > > setUpB(C) > console.log('Module C', B) > > export {C as default} > ``` > > */#!/*JoePea > > On Tue, Aug 9, 2016 at 9:59 PM, /#!/JoePea <[email protected]> wrote: > >> It seems that the environment I'm in (Meteor uses [reify]( >> https://github.com/benjamn/reify)) tries to evaluate A and B first, so I >> thought I could take advantage of "live bindings" by changing my modules to >> the following: >> >> ```js >> // --- Entrypoint >> >> import A from './app/A' >> console.log('Entrypoint', A) >> ``` >> >> ```js >> // --- Module A >> >> import C from './C' >> >> let A >> >> export >> function setUpA() { >> >> console.log('setUpA') >> console.log(C) >> >> A = class A extends C { >> // ... >> } >> >> } >> >> console.log('Module A', C, setUpA) >> >> export {A as default} >> ``` >> >> ```js >> // --- Module B >> >> import C from './C' >> >> let B >> >> export >> function setUpB() { >> >> console.log('setUpB', C) >> >> B = class B extends C { >> // ... >> } >> >> } >> >> console.log('Module B', C, setUpB) >> >> export {B as default} >> ``` >> >> ```js >> // --- Module C >> >> import A, {setUpA} from './A' >> import B, {setUpB} from './B' >> >> let C = class C { >> constructor() { >> // this may run later, after all three modules are evaluated, or >> // possibly never. >> console.log(A) >> console.log(B) >> } >> } >> >> setUpA() >> console.log('Module C', A) >> >> setUpB() >> console.log('Module C', B) >> >> export {C as default} >> ``` >> >> As you can see, modules A and B simply export the code that should be >> evaluated (note the live bindings). Then finally, the C module is evaluated >> last. At the end of the C module, you see that it calls `setUpA` and >> `setUpB`. When it fires `setUpA`, an error is thrown on the second >> `console.log` that `C` is undefined (or, specifically, `C.default` is >> `undefined` because the ES6 modules are compiled into CommonJS form). >> >> I thought that if `C` was a live binding, then it should be ready by the >> time the `setUpA` function is called. Should this in fact be the case? >> >> */#!/*JoePea >> >> On Tue, Aug 9, 2016 at 5:36 PM, John Lenz <[email protected]> wrote: >> >>> Without a way to load "later" (aka "soft") dependencies, ES6 module will >>> continue to be more or less broken for circular dependencies. >>> >>> On Tue, Aug 9, 2016 at 4:11 PM, Tab Atkins Jr. <[email protected]> >>> wrote: >>> >>>> On Tue, Aug 9, 2016 at 4:00 PM, /#!/JoePea <[email protected]> wrote: >>>> > True, and so that's why I'm wondering if the module system can see >>>> that it >>>> > can satisfy all module requirements if it simply evaluates module C >>>> first, >>>> > followed by A or B in any order. It is easy for us humans to see >>>> that. It >>>> > would be nice for the module system to see that as well (I'm not sure >>>> if >>>> > that is spec'd or not). >>>> >>>> That knowledge requires, at minimum, evaluating the rest of each >>>> module, beyond what is expressed in the `import` statements. That's >>>> assuming there's no dynamic trickery going on that would invalidate >>>> whatever assumptions it can draw from surface-level analysis. >>>> >>>> Because of this, only the `import` statements are declaratively >>>> available to the module system to work with. Based on that, it >>>> definitely can't make any ordering assumptions; all it knows is that A >>>> imports C, B imports C, and C imports both A and B, making a circular >>>> import. >>>> >>>> ~TJ >>>> _______________________________________________ >>>> es-discuss mailing list >>>> [email protected] >>>> https://mail.mozilla.org/listinfo/es-discuss >>>> >>> >>> >> >
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

