我有一个简单的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似乎被废弃了,不再工作了(编辑:实际上是这样,参见下面的我的回答 ),而且我找不到任何其他方法来同步加载脚本。总的来说,我认为ES6模块系统与旧的javascript包含系统之间的不兼容性是令人沮丧的。
作为参考,我使用的代码生成工具是Nearley语法编译器,它允许我从语法中引用我的词汇,并生成一个简单的JS解析器。
编辑:@yong建议了一个简洁的解决方案,只需在脚本中添加defer标签,例如
<script src="lexer.js" type="module"></script>
<script src="parser.js" defer></script>这似乎只是将parser.js的执行推迟到最后。但是,我没有提到我实际上有一个名为ES6的interpreter.js模块,需要在parser.js之后调用该模块。很抱歉,我没有早点提到这一点,我以为第一个问题的任何解决办法也会解决我的第二个问题。我修正了标题,以澄清我需要在普通JS脚本之前和之后运行ES6模块。本质上,我需要将这个简单的JS脚本集成到我的模块依赖图中。
EDIT2:我错了,延迟解决方案有效。见@Aviad或我自己的答案
发布于 2019-05-10 02:15:38
我认为这里的好做法是为此创建某种下载管理器(例如使用webpack块加载/动态导入)。
另一种选择是使用defer属性。请注意,defer指示脚本按遇到的顺序运行,因此,如果顺序正确,则可以假设调用interpreter.js时加载了interpreter.js。
链接:
发布于 2019-05-10 03:47:12
因此,我使用@Aviad的解决方案 (上面发布的)解决了这个问题,并将defer添加到我的所有脚本中,例如:
<script src="lexer.js" type="module" defer></script>
<script src="parser.js" defer></script>
<script src="interpreter.js" type="module" defer></script>它开始按照正确的顺序装载它们。整洁!尽管我认为需要注意的是,我还没有找到关于ES6模块的加载顺序的实际规范,因此似乎无法保证加载顺序(除了一个模块依赖于另一个模块,在这种情况下它将首先加载依赖项)。所以,虽然defer的把戏现在起作用了,但我认为它可能会在未来崩溃。
我还想提到的是,我的XMLHttpRequest同步脚本加载实际上是工作的,我只是遇到了一些范围问题。我不得不从eval的作用域调用window,因为通常parser.js是作为<script>标记加载在HTML中的,因此它希望作用域是window,所以我需要eval()来模拟,如下所示:
// load parser script synchronously
var req = new XMLHttpRequest();
req.open('GET', 'parser.js', false);
req.send(null);
eval.call(window, req.responseText);所以我想如果我需要的话我会有退路的。我还考虑手动将parser.js转换为一个ES6模块,但这省去了每次我重新生成它时转换它的麻烦。谢谢你的解决方案!
https://stackoverflow.com/questions/56069232
复制相似问题