From ReferenceError: can't access lexical declaration 'X' before initialization - JavaScript | MDN, there is an example of an invalid import:
a.js
(entry module):
import { b } from "./b.js"; export const a = 2;
b.js
:
import { a } from "./a.js"; console.log(a); // ReferenceError: Cannot access 'a' before initialization export const b = 1;
MDN explanation:
In this example, the imported variable
a
is accessed, but not initialized, because the evaluation ofa.js
is evaluated by the current moduleb.js
block.
I understand this to mean that importing a module means embedding the module's code into the line of the import statement. In other words, a.js
becomes like this when compiling:
console.log(a); // ReferenceError: Cannot access 'a' before initialization const b = 1; const a = 2;
Is this understanding correct? I don't see this explained in import - JavaScript | MDN. Due to variable hoisting, I don't know how to test this since rearranging the lines in a.js
doesn't change the result.
The code from the imported module is not just embedded ("pasted"), but exists in a separate closure. While this is certainly an oversimplification, I compared a module to a function, comparing the
export
statement to itsreturn
statement:Because modules import each other, they cannot be loaded in any order: pressing any button will cause a "Maximum call stack size exceeded" error.
But if you remove unnecessary lines (just populate a local variable which is then discarded), it will work.