如何包括js文件在另一个js文件?

如何将一个js文件包含到另一个js文件中,以坚持干燥的原理并避免代码重复。

829370 次浏览

这是不可能直接的。你也可以写一些预处理程序来处理它。

如果我的理解正确,那么以下是可以帮助实现这一目标的事情:

  • 使用预处理器,它将运行你的JS文件,例如寻找像“@import somefile.js”这样的模式,并将它们替换为实际文件的内容。Nicholas Zakas(Yahoo)用Java写了一个这样的库,你可以使用(http://www.nczonline.net/blog/2009/09/22/introducing-combiner-a-javascriptcss-concatenation-tool/)

  • 如果你正在使用Ruby on Rails,那么你可以尝试Jammit资产打包,它使用资产。Yml配置文件,在这里您可以定义您的包,其中可以包含多个文件,然后在您的实际网页中通过包名引用它们。

  • 尝试使用模块加载器,如RequireJS或脚本加载器,如LabJs,具有控制加载顺序以及利用并行下载的能力。

JavaScript目前还没有提供像CSS (@import)这样的“原生”方式来将JavaScript文件包含到另一个文件中,但上面提到的所有工具/方法都有助于实现你提到的DRY原则。我可以理解,如果你来自服务器端背景,这可能感觉不直观,但事情就是这样。对于前端开发人员来说,这个问题通常是“部署和打包问题”。

希望能有所帮助。

你需要写一份文件。写对象:

document.write('<script type="text/javascript" src="file.js" ></script>');

并将其放在主javascript文件中

只能在HTML页面中包含脚本文件,而不能在另一个脚本文件中包含脚本文件。也就是说,你可以编写JavaScript,加载你的“包含”脚本到同一页面:

var imported = document.createElement('script');
imported.src = '/path/to/imported/script';
document.head.appendChild(imported);

您的代码很有可能依赖于“包含的”脚本,但是,在这种情况下,它可能会失败,因为浏览器将异步加载“导入的”脚本。最好的办法是使用jQuery或YUI这样的第三方库,它们可以为您解决这个问题。

// jQuery
$.getScript('/path/to/imported/script.js', function()
{
// script is now loaded and executed.
// put your dependent JS here.
});

我不同意document.write技术(参见Vahan Margaryan的建议)。我喜欢document.getElementsByTagName('head')[0].appendChild(...)(见马特·鲍尔的建议),但有一个重要的问题:脚本执行顺序

最近,我花了很多时间重新生成main.js3,甚至著名的jQuery插件也使用相同的技术(参见src main.js4)来加载文件,但其他人也报告了这个问题。假设你有一个JavaScript库,它由许多脚本组成,一个loader.js加载所有的部分。有些部分是相互依赖的。想象你在每个<script>中包含另一个main.js脚本,它在loader.js之后使用来自loader.js的对象。问题是,有时main.jsloader.js加载所有脚本之前执行。在main.js脚本中使用$(document).ready(function () {/*code here*/});没有帮助。在loader.js中使用级联onload事件处理程序将使脚本加载顺序而不是并行,并且将使使用main.js脚本变得困难,它应该只是loader.js之后的某个地方的一个include。

通过在我的环境中重现这个问题,我可以看到,在Internet Explorer 8中,脚本的执行顺序会因包含JavaScript而有所不同。如果您需要包含相互依赖的脚本,这将是一个非常困难的问题。该问题在并行加载Javascript文件中描述,建议的解决方法是使用document.writeln:

document.writeln("<script type='text/javascript' src='Script1.js'></script>");
document.writeln("<script type='text/javascript' src='Script2.js'></script>");

因此,在“脚本是并行下载的,但按照它们写入页面的顺序执行”的情况下,从document.getElementsByTagName('head')[0].appendChild(...)技术改为document.writeln技术后,我再也没有看到这个问题了。

所以我建议你使用document.writeln

更新:如果有人感兴趣,他们可以尝试在Internet Explorer中加载(并重新加载)页面(页面使用document.getElementsByTagName('head')[0].appendChild(...)技术),然后与使用document.writeln固定版本进行比较。(该页的代码是相对肮脏的,不是来自我,但它可以用来重现问题)。