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.
P粉1658237832023-09-17 00:53:49
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 its return
statement:
function a_js() { var b = b_js(); // 不必要的行 return 2; } function b_js() { var a = a_js(); console.log(a); return 1; }
<button onclick="a_js()">import a.js</button> <button onclick="b_js()">import b.js</button>
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.