1

I have a bug in my code that has something to do with imports and exports. My understanding was that all imports are handled before any code is run, however now I am not so sure. I have the following MRE below, in three files.

index.html

<!-- index.html (Program entry point) -->
<html>
   <head>
      <script src="A.js" type="module"></script>
   </head>
    <body></body>
</html>

A.js

// A.js

import './B.js';

export default 'Hello World';

B.js

// B.js

import message from './A.js';

console.log(message);

When run, produces this error: Uncaught ReferenceError: Cannot access 'message' before initialization at B.js:5

To make things stranger, if I make index.html instead point to B.js, then the program runs fine (Without changing any other files).

My prior understanding was that all imports/exports would be evaluated first, and only then the rest of the code run. However this snippet seems to suggest that the 'import chain' is followed down, and then each file evaluated from the bottom up, bringing each export with it. Meaning that if a file 'lower' on the import tree needs an export from something above it, then it just doesn't work. But to me that would be very strange and counter-intuative behaviour.

So my question is, what is the cause? Is my understanding of the order how imports/exports are evaluated wrong? Or is this a bug in Chrome/Edge? (Unfortunately couldn't test any others) Or am I missing something else???

Why does this behave the way it does?

Thanks for any help

- Keldan

Keldan Chapman
  • 665
  • 5
  • 21
  • 1
    You have circular references in there; both scripts import each other. That's a bad idea in general. –  Dec 07 '20 at 11:59
  • You can't import from A to B and vice versa. Imports can only go in one direction. https://stackoverflow.com/questions/38841469/how-to-fix-this-es6-module-circular-dependency – Zsolt Meszaros Dec 07 '20 at 12:01
  • @ZsoltMeszaros So why does the code work when index.html first calls B.js instead? There is still circular imports. Or do you mean that it is just bad practice? – Keldan Chapman Dec 07 '20 at 12:25

1 Answers1

0

In A.js don't import B.js

// A.js

export default 'Hello World';

Otherwise you will have a circular dependency.

Jonathan Irwin
  • 5,009
  • 2
  • 29
  • 48
  • 1
    I understand that its a circular dependancy, but even with the circular dependancy, the code works when I point index.html at B.js, but now when I point it at A.js. I want to know why? This is a simplified example, in my real code I can't so easily just not import B.js. – Keldan Chapman Dec 08 '20 at 04:33
  • Add some breakpoints to your code in each file and step throw the execution. I think you will find you kind of just get lucky with the order objects are initialised when pointing to B directly – Jonathan Irwin Dec 08 '20 at 07:28