How to solve this basic ES6-module circular dependency problem?
Logan Smyth
loganfsmyth at gmail.com
Thu Aug 11 17:26:25 UTC 2016
Keep in mind `let A = A;` is a TDZ error in any real ES6 environment.
The example I posted works properly with Babel's live-binding
implementation and should require less repetition. What were your thoughts
on it?
On Thu, Aug 11, 2016 at 12:23 AM, /#!/JoePea <joe at trusktr.io> wrote:
> Alright, so I believe I have found the solution. It is not possible to
> guarantee a certain module evaluation order, but using some clever (but
> tedious) conditional checking I believe the problem is solved (with two
> caveats listed after):
>
> ```js
> // --- Entrypoint
> import A from './A'
> console.log('Entrypoint', new A)
> ```
>
> ```js
> // --- Module A
>
> import C from './C'
> import {setUpB} from './B'
>
> let A
>
> export
> function setUpA(C) {
>
> if (!A) {
> A = class A extends C {
> // ...
> }
> }
>
> }
>
> if (setUpA && C) setUpA(C)
> if (setUpB && C) setUpB(C)
>
> export {A as default}
> ```
>
> ```js
> // --- Module B
>
> import C from './C'
> import {setUpA} from './A'
>
> let B
>
> export
> function setUpB(C) {
>
> if (!B) {
> B = class B extends C {
> // ...
> }
> }
>
> }
>
> if (setUpA && C) setUpA(C)
> if (setUpB && C) setUpB(C)
>
> export {B as default}
> ```
>
> ```js
> // --- Module C
>
> import A, {setUpA} from './A'
> import B, {setUpB} from './B'
>
> class C {
> constructor() {
> // this may run later, after all three modules are evaluated, or
> // possibly never.
> console.log(A)
> console.log(B)
> }
> }
>
> if (setUpA && C) setUpA(C)
> if (setUpB && C) setUpB(C)
>
> export {C as default}
> ```
>
> The caveat is that this fails in both Babel environments and in Rollup.
> For it to work in Babel environments, `let A` and `let B` have to be
> changed to `let A = A` and `let B = B`, as per the [fault in Babel's
> ES2015-to-CommonJS implementation](https://github.com/meteor/meteor/
> issues/7621#issuecomment-238992688) pointed out by Ben Newman. And it
> fails in Rollup because Rollup [isn't really creating live bindings](
> https://github.com/rollup/rollup/issues/845), which is fine in most
> cases, but doesn't work with these circular dependencies. The Rollup output
> does not create the C reference before it is ever used in the first pair of
> conditional checks, unlike what (I think) would happen with real live
> bindings (please correct me if wrong). To understand what I mean in the
> case of Rollup, just run `if (FOO) console.log(FOO)` in your console, and
> you'll get an error because FOO is not defined. Had the bindings been live,
> then FOO *would* be defined.
>
>
>
> */#!/*JoePea
>
> On Wed, Aug 10, 2016 at 5:04 PM, /#!/JoePea <joe at trusktr.io> wrote:
>
>> I found a solution that works in environments compiled by Babel, using
>> the [workaround suggested by Ben Newman](https://github.com/met
>> eor/meteor/issues/7621#issuecomment-238992688):
>>
>> ```js
>> // --- Module A
>>
>> import C from './C'
>>
>> let A = A // @benjamn's workaround applied
>>
>> export
>> function setUpA(C) {
>>
>> A = class A extends C {
>> // ...
>> }
>>
>> }
>>
>> export {A as default}
>> ```
>>
>> ```js
>> // --- Module B
>>
>> import C from './C'
>>
>> let B = B // @benjamn's workaround applied
>>
>> export
>> function setUpB(C) {
>>
>> B = class B extends C {
>> // ...
>> }
>>
>> }
>>
>> 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)
>> setUpB(C)
>>
>> export {C as default}
>> ```
>>
>> ```js
>> // --- Entrypoint
>>
>> import A from './A'
>> console.log('Entrypoint', new A) // runs the console.logs in the C
>> constructor.
>> ```
>>
>>
>> Although that works in my environment which is compiled from ES6 modules
>> to CommonJS by Babel, it [doesn't work in Rollup.js](http://goo.gl/PXXBKI),
>> and may not work in other ES6 module implementations.
>>
>> Is there some solution that will theoretically work in any ES6 module
>> environment?
>>
>> */#!/*JoePea
>>
>
>
> _______________________________________________
> 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/20160811/a7529658/attachment-0001.html>
More information about the es-discuss
mailing list