【发布时间】:2019-09-27 20:51:31
【问题描述】:
我有一个纯 JS 脚本 parser.js(从工具生成),它依赖于 ES6 模块 lexer.js 中定义的变量。在我的 ES6 模块中,我已经将变量导出到 window 对象,因此可以从 parser.js 访问它们。但是,我需要在运行脚本之前以某种方式运行该 ES6 模块。而且似乎没有任何方法可以这样做。
尝试 1:在包含我的脚本之前尝试同步加载 ES6 模块
我在我的 HTML 中尝试过这样的事情。
<script src="lexer.js" type="module"></script>
<script src="parser.js"></script>
但它似乎没有按顺序运行。 lexer.js 在parser.js 之后运行
尝试 2:尝试在 ES6 模块中同步加载脚本
我尝试像这样围绕我的解析器脚本创建一个包装器 ES6 模块
// 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);
但是,似乎同步 XMLHttpRequests 已被弃用并且不再起作用(编辑:实际上它们确实如此,请参阅下面的my answer),而且我找不到任何其他同步加载脚本的方法。总的来说,我会说 ES6 模块系统和旧的 javascript 包含系统之间的不兼容,实在令人沮丧。
附:作为参考,我使用的代码生成工具是Nearley grammar compiler,它允许我从语法中引用我的词法分析器,并生成一个普通的JS解析器。
编辑:@yong-quan 提出了一个简洁的解决方案,只需将defer 放在脚本包含标签中,例如
<script src="lexer.js" type="module"></script>
<script src="parser.js" defer></script>
看起来这只是将parser.js 的执行推迟到最后。但是,我没有提到我实际上有一个名为 interpreter.js 的 ES6 模块,它需要在 parser.js 之后调用。很抱歉没有早点提到,我认为任何对我的第一个问题有效的解决方案也可以解决我的第二个问题。我修正了标题以澄清我需要 ES6 模块在 之前和之后 我的纯 JS 脚本运行。本质上,我需要将这个纯 JS 脚本集成到我的模块依赖图中。
EDIT2:我错了,延迟解决方案有效。请参阅下面的@Aviad 或我自己的答案
【问题讨论】:
-
你试过
<script src="parser.js" defer></script>吗? -
哇,成功了,你是救生员!如果您将评论作为答案,我会接受:)
-
实际上等等,我不确定这是否适合我的需要,因为我实际上有一个 ES6 模块必须在
parser.js之后运行,称为interpreter.js。我没有在问题中提到它,因为我认为第一个问题的任何解决方案都可以解决第二个问题,但我想情况并非如此。我将在我的问题中包括最后一部分。感谢您的建议 -
如果 parser.js 在 html 中出现在其他两个脚本之前,那么您可以推迟解析器和解释器(它将按此顺序执行),没有 defer 的词法分析器将是第一个。
-
你是对的,@aviad 提出了同样的建议。事实上,我只是在所有脚本中添加了
defer,包括lexer.js,它仍然以正确的顺序执行。很奇怪,但对我有用:)
标签: javascript ecmascript-6 es6-modules