在JavaScript开发中,经常需要在不同的文件中包含和引用代码。然而,JavaScript本身并没有提供直接包含其他文件的功能,这就需要寻找解决方案。本文将介绍一种实现JavaScript文件包含功能的引擎,它能够处理文件间的依赖关系,并实现模块化。
在第一部分和第二部分中,讨论了JavaScript文件包含的挑战和一些初步的解决方案。现在,将深入探讨一个更加完善的解决方案,它能够在各种情况下工作,并且具有较小的缺陷。
目标是创建一个引擎,它能够在JavaScript文件中包含其他JavaScript文件。这个引擎需要能够处理函数声明、对象声明,并且能够处理文件间的依赖关系。
在之前的讨论中,发现了一个关键问题:当脚本开始执行时,它会一直执行下去,这限制了只能包含函数声明和对象声明。为了解决这个问题,提出了一个创新的方法:使用错误来停止脚本的执行。
可以通过抛出一个错误来停止脚本的执行。然后,可以通过覆盖window.onerror
事件来控制错误信息的显示。这样,可以在需要的时候重新执行脚本。
$include = function() {
// code ...
throw new Error("Special Error");
}
window.onerror = function() {
// we can check here to see if the message
// of the error is not "Special Error"
// and then show it to the user
}
为了解决执行脚本时的问题,可以使用iFrame。通过iFrame,可以读取文件的头部(现在不一定非得是函数),然后使用eval
来执行主体部分。但是,eval
在处理资源时存在问题,因此不适合执行大段代码。
可以创建一个HTML文件,它将正常加载脚本,并只执行$include
函数,将当前加载在iFrame中的文件的依赖项传递给父文档。然后,可以抛出错误。这样,当文件被加载时,它也会被缓存,当主文档需要时,它不会再次从服务器加载。
与前两部分的实现相比,这个实现更加复杂,因此不适合在这里粘贴。但是,已经介绍了最重要的部分:总体思路以及如何克服不同障碍。可以下载这个实现并进行研究。(别忘了,有两个文件:IncludingEngine.js
和LoadFile.htm
,它们一起完成了这项工作)。
下面的图表展示了这个解决方案的强大功能:
这个解决方案不仅可以在线工作,还可以离线工作。它不使用eval
,并且可以检测并显示形成循环依赖的文件。现在,可以说,第一部分中提出的挑战终于得到了满足。
这个实现的最新版本可以在IncludingEngine.jsFramework.com
找到。这里是“JavaScriptIncluding Engine”系列文章的所有部分: