I eliminated the circular dep, and all is well now. I suppose I learned
something that is really good to know if ever dealing with circular deps:
Always import circular deps after non-circular deps.
f.e.
this is bad:
```js
import CircularDep from 'somewhere'
import NonCircularDep from 'another-place'
```
and this is good:
```js
import NonCircularDep from 'another-place'
import CircularDep from 'somewhere'
```
This ensures that the non-circular deps are evaluated and ready before
hoisted circular-dep init functions are called (i.e. when using the
var/initDep trick).
*/#!/*JoePea
On Sat, Oct 8, 2016 at 7:46 PM, /#!/JoePea <joe at trusktr.io> wrote:
> Yep, I believe that the first error was solved by moving the import
> statement to the top!
>> As for the second error, I think (but not yet sure) that the problem might
> be due to the circular dependency `src/motor-html/node ->
> src/motor/Transformable -> src/motor/Sizeable -> src/motor/Scene ->
> src/motor/ImperativeBase -> src/motor/Node -> src/motor-html/node`.
>> The problem will be solved after I re-organize some things, but if you
> have any suggestions it would be greatly appreciated!
>> I'm still not sure why it works in Reify and not in Webpack.
>> - Joe
>>> */#!/*JoePea
>> On Sat, Oct 8, 2016 at 5:23 PM, /#!/JoePea <joe at trusktr.io> wrote:
>>> Hello Logan, I wonder if I can borrow your expertise for just a moment:
>>>> I ran into another problem. Suppose I have the following code which is
>> very similar to the code I had before (using the `var` trick along with
>> `initC` function), but now Module C imports `someFunction` from a newly
>> added module.
>>>> The problem is that module B will be evaluated before both Module C and
>> the utilities module. When `initC` is called inside of the B module, the
>> `initC` function will try and call `someFunction` but there will be an
>> error because the utilities module was not yet evaluated, so `someFunction`
>> is undefined.
>>>> What would you recommend as a solution?
>>>> Here's the code:
>>>> ```js
>> // --- Entrypoint
>> import A from './A'
>> console.log('Entrypoint', new A)
>> ```
>>>> ```js
>> // --- Module A
>>>> import C, {initC} from './C'
>>>> console.log('module A')
>> initC()
>>>> class A extends C {
>> // ...
>> }
>>>> export {A as default}
>> ```
>>>> ```js
>> // --- Module B
>>>> import C, {initC} from './C'
>>>> console.log('module B')
>> initC()
>>>> class B extends C {
>> // ...
>> }
>>>> export {B as default}
>> ```
>>>> ```js
>> // --- Module C
>>>> import A from './A'
>> import B from './B'
>> import {someFunction} from './utilities'
>>>> console.log('module C')
>>>> var C
>>>> initC()
>>>> export function initC(){
>> if (C) return
>>>> console.log('initC!!!')
>> someFunction()
>>>> C = class C {
>> constructor() {
>> // this may run later, after all three modules are evaluated,
>> or
>> // possibly never.
>> console.log(A)
>> console.log(B)
>> }
>> }
>> }
>>>> export {C as default}
>> ```
>>>> ```js
>> // utilities.js
>>>> var someFunction = () => {...}
>>>> export {
>> someFunction,
>> }
>> ```
>>>> I think a possible (though strange) solution is to change the import
>> order in Module C, f.e.:
>>>> ```js
>> import A from './A'
>> import B from './B'
>> import {someFunction} from './utilities'
>> ```
>>>> I haven't actually tested that example code, but I believe I'm having a
>> problem like this with Webpack+Babel here: https://github.com/trusktr/inf>> amous/tree/circular-dep-bug
>>>> In this case, there is a circular dependency between `src/motor/Scene`
>> and `src/motor/Sizeable` (which I've already planned to eliminate, but am
>> still curious about how I would solve it without eliminating the circular
>> dep). The modules import the defaults of each other, and I'm using the `var
>> Sizeable/initSizeable` trick. However, there's a third module, `Utility.js`
>> from which the `Sizeable` module needs to import something to use inside of
>> the `initSizeable` function.
>>>> You can experience the error by simply opening `motor-scratch.html` in
>> your browser, in which case you'll get an error like
>>>> ```
>> Sizeable.js:328: Uncaught TypeError: Cannot read property '
>> makeLowercaseSetterAliases' of undefined
>> ```
>>>> where `makeLowercaseSetterAliases` is akin to the `someFunction` of my
>> earlier example. The odd thing is that everything works fine in Meteor's
>> Reify environment, and I'm only getting this error when using the bundle
>> made by Webpack+Babel.
>>>> If I re-order the dependencies in `src/motor/Sizeable` so that they look
>> like this:
>>>> ```js
>> import { makeLowercaseSetterAliases } from './Utility'
>> import XYZValues from './XYZValues'
>> import Motor from './Motor'
>> import Scene from './Scene'
>> ```
>>>> then the error goes away, but I get another error:
>>>> ```
>> node.js:129: Uncaught TypeError: Cannot read property 'prototype' of
>> undefined
>> ```
>>>> I have a feeling that moving the import to the beginning solved the
>> problem, and that now I have another problem...
>>>> If you'd like to test changes (f.e. moving the import statement), you can
>> simply:
>>>> ```
>> npm install
>> npm run watch
>> ```
>>>> which will automatically compile the global.js file after making changes
>> to anything in `src`, and you can reload the page in your browser.
>>>> Any and all input you may have on this would be greatly appreciated!
>>>> Thanks a ton!
>>>> All the best,
>> - Joe
>>>>>> */#!/*JoePea
>>>> On Tue, Aug 23, 2016 at 8:55 PM, Logan Smyth <loganfsmyth at gmail.com>
>> wrote:
>>>>> > Should I open an issue there? And I think you're right about it
>>> should throw, because it is strange that the function can be executed
>>> before the module is ever evaluated (that seems like it should be
>>> impossible), and therefore a TDZ error would happen because the `let` line
>>> wasn't theoretically evaluated yet.
>>>>>> If you'd like, go for it. To note, Babel 6 doesn't implement TDZ at all
>>> at the moment anyway.
>>>>>> > I don't see how it is possible with `var`. How is it that `var`s or
>>> `function`s can be hoisted *out of* the module? Is that part of spec? If
>>> so, then that is different hoisting from function-based hoisting of pre-ES6.
>>>>>> They are not hoisted out of the module. It seems like you may be
>>> misunderstanding how modules are linked together.
>>>>>> > Pre-ES6 "hoisting" in javascript happens on boundaries set by
>>> `function`s, and I thought that modules would be similar to function
>>> bodies, and therefore I thought that hoisting would be limited to within a
>>> module and did not expect hoisting to go beyond the module boundary to some
>>> scope that encompasses multiple modules. That to me is a different type of
>>> "hoisting" than what I know from pre-ES6 JavaScript's function-scope
>>> hoisting so it isn't necessarily the "same way it'd work with other cases
>>> of hoisting"; there is definitely some ES6-module-specific stuff happening
>>> that is a little different from pre-ES6 function-scope hoisting. (sidenote:
>>> I've asked the awesome Axel of 2ality to add these useful details to his
>>> articles.)
>>>>>> Hoisting of var and functions behaves the same way in ES6 and in ES5 and
>>> you are correct there is no "beyond the module boundary". Let's clarify
>>> hoisting in a function.
>>>>>> ```
>>> function fn() {
>>> console.log(inner());
>>>>>> function inner(){ return "hello world"; }
>>> }
>>> fn();
>>> ```
>>> in this context, when an engine executes `fn()`, before any execution
>>> has happened inside the `fn`, the engine does the following
>>>>>> 1. Create the conceptual function "scope", which exists immediately as
>>> soon as the function is called.
>>> 2. Look for all function declarations inside `fn` and create their
>>> variables and assign their values to point to function objects. This is
>>> "function hoisting".
>>> 3. Look for all var declarations inside `fn` and create variables with
>>> the value `undefined`. This is "var hoisting".
>>> 4. Look for all let/const declarations, and create uninitialized
>>> variables (these will throw when accessed)
>>> 5. A bunch of other stuff I'm skipping
>>> 6. Execute the function body itself.
>>>>>> A very similar process happens for modules. You can think of it like
>>> steps 1-4 running, then before executing the module body (step 6), we
>>> recursively do this same process on every imported module. So by the time
>>> any module gets to step 6, every imported module, and every module those
>>> modules depend on, will have executed step 1-4, and have scopes that have
>>> been created, and variables that have been declared (possibly with a value,
>>> or possibly left uninitialized).
>>>>>> So by the time you get to step 6, there isn't a "beyond the module
>>> boundary", when you access the imported variables in your module, the JS
>>> engine will reach across the module boundary for you, to get the current
>>> value of the variable in the imported module. This behavior of reaching
>>> across module scopes is what module syntax allows, and it is what enables
>>> live binding.
>>>>>> Because of this live behavior, if you imported something that was
>>> defined with `let`, like your `let C;` example, it would cause a TDZ error
>>> because the variable was still "uninitialized", whereas if you make it a
>>> `var`, it will be initialized to `undefined`.
>>>>>> > If I use the `var` method as you proposed (which is working in my
>>> Babel env), should I expect that method to always work in any theoretical
>>> 100%-implemented-to-spec ES6 environment, not just in Babel?
>>>>>> Correct.
>>>>>> On Tue, Aug 23, 2016 at 8:17 PM, /#!/JoePea <joe at trusktr.io> wrote:
>>>>>>> > Damn, that's a Babel bug with the block scoping logic. That said, as
>>>> in my example, that needs to be `var C;` anyway, `let` would throw (in an
>>>> environment with working TDZ anyway). Changing it to `var` also stops the
>>>> duplicate printing.
>>>>>>>> Should I open an issue there? And I think you're right about it should
>>>> throw, because it is strange that the function can be executed before the
>>>> module is ever evaluated (that seems like it should be impossible), and
>>>> therefore a TDZ error would happen because the `let` line wasn't
>>>> theoretically evaluated yet.
>>>>>>>> I don't see how it is possible with `var`. How is it that `var`s or
>>>> `function`s can be hoisted *out of* the module? Is that part of spec? If
>>>> so, then that is different hoisting from function-based hoisting of pre-ES6.
>>>>>>>> I was under the impression that the modules were like a function, and
>>>> hoisting would only happen inside the module. In that case, the `initC`
>>>> function could not possibly be available until the `C` module itself was
>>>> evaluated, so I was expecting for there to be an `undefined` error when
>>>> `initC` was called before the `C` module was evaluated.
>>>>>>>> You say that
>>>>>>>> > which means you can import and call a function declaration from any
>>>> module, even if that module hasn't started the `Evaluation` phase yet, the
>>>> same way it'd work with other cases of hoisting, where execution hasn't
>>>> reached the function declaration, but it is available early.
>>>>>>>> Which makes sense based on what I see happening, but it seems strange
>>>> because it means that the scope of the module (as far as hoisting is
>>>> concerned) is not the module itself, but rather some outer scope that wraps
>>>> *all* the modules that import a given symbol.
>>>>>>>> You said,
>>>>>>>> > the same way it'd work with other cases of hoisting, where execution
>>>> hasn't reached the function declaration, but it is available early.
>>>>>>>> Pre-ES6 "hoisting" in javascript happens on boundaries set by
>>>> `function`s, and I thought that modules would be similar to function
>>>> bodies, and therefore I thought that hoisting would be limited to within a
>>>> module and did not expect hoisting to go beyond the module boundary to some
>>>> scope that encompasses multiple modules. That to me is a different type of
>>>> "hoisting" than what I know from pre-ES6 JavaScript's function-scope
>>>> hoisting so it isn't necessarily the "same way it'd work with other cases
>>>> of hoisting"; there is definitely some ES6-module-specific stuff happening
>>>> that is a little different from pre-ES6 function-scope hoisting. (sidenote:
>>>> I've asked the awesome Axel of 2ality to add these useful details to his
>>>> articles.)
>>>>>>>> If I use the `var` method as you proposed (which is working in my Babel
>>>> env), should I expect that method to always work in any theoretical
>>>> 100%-implemented-to-spec ES6 environment, not just in Babel?
>>>>>>>> If so, then this may be one of the rare cases of "when we'd want to
>>>> actually use `var` instead of `let`" besides for cases when we want pre-ES6
>>>> hoisting which I think should be generally avoided in order to make code
>>>> less error-prone and easier to understand. This behavior would have been
>>>> nearly-impossible to know about without the knowledge gained from this
>>>> conversation (or from reading the spec in depth which can be difficult).
>>>>>>>>>>>>>>>> */#!/*JoePea
>>>>>>>> On Tue, Aug 16, 2016 at 10:48 AM, Logan Smyth <loganfsmyth at gmail.com>
>>>> wrote:
>>>>>>>>> > Your `initC` solution is working in Meteor (Babel + Reify) and
>>>>> Webpack+Babel, but the `initC` logic seems to run twice, as if there are
>>>>> two C variables instead of one. The following code is based on yours, and
>>>>> the `console.log('initC!!!')` statement unexpectedly executes twice, and
>>>>> you'll see output like this:
>>>>>>>>>> Damn, that's a Babel bug with the block scoping logic. That said, as
>>>>> in my example, that needs to be `var C;` anyway, `let` would throw (in an
>>>>> environment with working TDZ anyway). Changing it to `var` also stops the
>>>>> duplicate printing.
>>>>>>>>>> > I'm also not sure how `initC` can be defined when it is called in
>>>>> the B module, which is evaluated before C and A. The evaluation order is B,
>>>>> C, A (depth first). Does the `initC` function get hoisted into a scope
>>>>> common with all three modules? That is the only way that would seem to
>>>>> explain it, but that seems to go against the intuition I had that each
>>>>> module had it's own module scope (as if it were wrapped inside a
>>>>> `function() {}`, and therefore I thought the `initC` function would be
>>>>> hoisted within the C module, and that with B being evaluated first I
>>>>> thought an "undefined" error would be thrown when it tried to execute
>>>>> `initC` (but that is not happening!). How is it that `initC` can be
>>>>> available to the B module before C is evaluated?
>>>>>>>>>> There are two separate pieces to executing a module, `Instantiation`,
>>>>> and `Evaluation`, which are what comes into play here. When you tell a JS
>>>>> environment to execute a file, it will instantiate every ES6 module in
>>>>> dependency graph before beginning to execute _any_ of the modules. Babel
>>>>> does its best to simulate this behavior, though it's not perfect at it. One
>>>>> of the things that happens during module instantiation is that hoisted
>>>>> declarations are initialized, which means you can import and call a
>>>>> function declaration from any module, even if that module hasn't started
>>>>> the `Evaluation` phase yet, the same way it'd work with other cases of
>>>>> hoisting, where execution hasn't reached the function declaration, but it
>>>>> is available early.
>>>>>>>>>> This behavior is why you can't use `let C` there, because when `B` is
>>>>> being evaluated, the `let C` line won't have run because the Evaluation
>>>>> phase of `C` hasn't started yet. You can however access the `initC`
>>>>> function because it is a function declaration. As long as there are no TDZ
>>>>> errors in what you're doing, that function can do whatever it would like,
>>>>> assuming it doesn't depend on other stuff that would require `Evaluation`
>>>>> to have finished in `C`, the same as what happens with hoisting normally.
>>>>> That means for instance you couldn't do
>>>>>>>>>> import B from './B';
>>>>> var SOME_CONSTANT = "hello";
>>>>>>>>>> export function initC(){
>>>>> return SOME_CONSTANT;
>>>>> }
>>>>>>>>>> because calling `initC` here would return `undefined` if called from
>>>>> inside a dependency cycle from `B`.
>>>>>>>>>> On Sat, Aug 13, 2016 at 9:09 PM, /#!/JoePea <joe at trusktr.io> wrote:
>>>>>>>>>>> Hi Logan,
>>>>>>>>>>>> > The example I posted works properly with Babel's live-binding
>>>>>> implementation and should require less repetition. What were your thoughts
>>>>>> on it?
>>>>>>>>>>>> Your `initC` solution is working in Meteor (Babel + Reify) and
>>>>>> Webpack+Babel, but the `initC` logic seems to run twice, as if there are
>>>>>> two C variables instead of one. The following code is based on yours, and
>>>>>> the `console.log('initC!!!')` statement unexpectedly executes twice, and
>>>>>> you'll see output like this:
>>>>>>>>>>>> ```
>>>>>> module B
>>>>>> initC!!!
>>>>>> module C
>>>>>> initC!!!
>>>>>> module A
>>>>>> function A() { ... }
>>>>>> function B() { ... }
>>>>>> Entrypoint A {}
>>>>>> ```
>>>>>>>>>>>> I'm also not sure how `initC` can be defined when it is called in the
>>>>>> B module, which is evaluated before C and A. The evaluation order is B, C,
>>>>>> A (depth first). Does the `initC` function get hoisted into a scope common
>>>>>> with all three modules? That is the only way that would seem to explain it,
>>>>>> but that seems to go against the intuition I had that each module had it's
>>>>>> own module scope (as if it were wrapped inside a `function() {}`, and
>>>>>> therefore I thought the `initC` function would be hoisted within the C
>>>>>> module, and that with B being evaluated first I thought an "undefined"
>>>>>> error would be thrown when it tried to execute `initC` (but that is not
>>>>>> happening!). How is it that `initC` can be available to the B module before
>>>>>> C is evaluated?
>>>>>>>>>>>> This is the code I have:
>>>>>>>>>>>> ```js
>>>>>> // --- Entrypoint
>>>>>> import A from './A'
>>>>>> console.log('Entrypoint', new A)
>>>>>> ```
>>>>>>>>>>>> ```js
>>>>>> // --- Module A
>>>>>>>>>>>> import C, {initC} from './C'
>>>>>>>>>>>> console.log('module A')
>>>>>> initC()
>>>>>>>>>>>> class A extends C {
>>>>>> // ...
>>>>>> }
>>>>>>>>>>>> export {A as default}
>>>>>> ```
>>>>>>>>>>>> ```js
>>>>>> // --- Module B
>>>>>>>>>>>> import C, {initC} from './C'
>>>>>>>>>>>> console.log('module B')
>>>>>> initC()
>>>>>>>>>>>> class B extends C {
>>>>>> // ...
>>>>>> }
>>>>>>>>>>>> export {B as default}
>>>>>> ```
>>>>>>>>>>>> ```js
>>>>>> // --- Module C
>>>>>>>>>>>> import A from './A'
>>>>>> import B from './B'
>>>>>>>>>>>> console.log('module C')
>>>>>> let C
>>>>>>>>>>>> export function initC(){
>>>>>> if (C) return
>>>>>>>>>>>> console.log('initC!!!')
>>>>>>>>>>>> C = class C {
>>>>>> constructor() {
>>>>>> // this may run later, after all three modules are
>>>>>> evaluated, or
>>>>>> // possibly never.
>>>>>> console.log(A)
>>>>>> console.log(B)
>>>>>> }
>>>>>> }
>>>>>> }
>>>>>>>>>>>> initC()
>>>>>>>>>>>> export {C as default}
>>>>>> ```
>>>>>>>>>>>> */#!/*JoePea
>>>>>>>>>>>> On Thu, Aug 11, 2016 at 10:26 AM, Logan Smyth <loganfsmyth at gmail.com>
>>>>>> wrote:
>>>>>>>>>>>>> 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/meteor/meteor/issues/7621#issueco>>>>>>>>> mment-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/20161009/8305f877/attachment-0001.html>