I have a module called fooModule
. Inside this module, I import fooModule
(itself):
import * as fooModule from './fooModule';
export function logFoo() {
console.log(fooModule)
}
When logFoo()
is called, I can see all of the exports of the fooModule.
How does this work?
Circular dependencies are no problem for declarative imports/exports. In your case, the circle is of minimal length though :-)
The solution is that an
import
does not import a value into a variable, but that it makes a variable a reference to the exported variable. Have a look here for an example of a mutable variable, and at this question for exact terminology.And it's the same for module namespace objects - their properties are just getters that resolve to the actual exported variable.
So when your module is loaded and evaluated, the following steps occur:
export
andimport
declarations to build a dependency graphfooModule
variable is created and instantiated to an object with the exported names of the module, which are known to be["logFoo"]
. ThefooModule.logFoo
property becomes a getter that will evaluate to thelogFoo
variable in the module scope (if you had usedexport {A as B}
, thenfooModule.B
would resolve toA
, but in your case both names are the same).logFoo
, and function declarations are initialised (i.e.logFoo
gets assigned the function)Now when you call
logFoo
in a module that imports it,fooModule
will refer to the namespace that containslogFoo
. No magic :-)