I have a plain JS script, parser.js
(generated from a tool) that depends on variables defined in an ES6 Module, lexer.js
. In my ES6 module I have already exported the variables to the window
object so they are accessible from parser.js
. However, I need to somehow run that ES6 module before running the script. And there doesn't seem to be any way to do so.
Attempt 1: Try to load ES6 Module synchronously before including my script
I tried some thing like this in my HTML.
<script src="lexer.js" type="module"></script>
<script src="parser.js"></script>
But it doesn't seem to run in order. lexer.js
runs after parser.js
Attempt 2: Try to load script synchronously inside an ES6 Module
I tried creating a wrapper ES6 module around my parser script like so
// use import to run the module and load variables into the window
import { lexer } from './lexer.js';
// load parser script synchronously
var req = new XMLHttpRequest();
req.open('GET', 'parser.js', false);
req.send(null);
eval(req.responseText);
However, it seems like synchronous XMLHttpRequests are deprecated and don't work anymore (edit: actually they do, see my answer below), and I can't find any other way to synchronously load a script. Overall, I would say the incompatibilities between the ES6 module system and the old javascript include system, to be beyond frustrating.
P.S. For reference, the code generation tool I am using is the Nearley grammar compiler, which allows me to reference my lexer from the grammar, and generates a plain JS parser.
EDIT: @yong-quan suggested a neat solution, to simply put defer
in the script include tag, eg
<script src="lexer.js" type="module"></script>
<script src="parser.js" defer></script>
It seems like this simply defers the execution of parser.js
to the end. However, I failed to mention that I actually have an ES6 module called interpreter.js
that needs to be called after parser.js
. Sorry for not mentioning that sooner, I assumed that whatever solution worked for my first issue would also solve my second issue. I fixed the title to clarify that I need ES6 modules to run before and after my plain JS script. Essentially, I need to integrate this plain JS script into my module dependency graph.
EDIT2: I was wrong, the defer solution works. See @Aviad or my own answer below