我如何将一个js文件包含到另一个js文件中,以坚持DRY原则并避免代码重复。
如何在另一个js文件中包含js文件?
您只能在 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(...)
(参见Matt Ball 的建议),但有一个重要问题:脚本执行顺序。
最近,我花了很多时间重现一个类似的问题,甚至著名的 jQuery 插件也使用相同的技术(请参阅此处的src )来加载文件,但其他人也报告了该问题。想象一下,你有一个由许多脚本组成的 JavaScript 库,一个loader.js
加载所有部分。有些部分是相互依赖的。想象一下,你有其他main.js
每个脚本<script>
,它使用从物体loader.js
后,立即loader.js
。问题是有时main.js
在所有脚本加载之前执行loader.js
。脚本$(document).ready(function () {/*code here*/});
内部的使用main.js
无济于事。级联onload
事件处理程序在loader.js
将使脚本加载顺序而不是并行,并使main.js
脚本难以使用,脚本应该只是在loader.js
.
通过在我的环境中重现该问题,我可以看到 **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
。(页面代码比较脏,不是我写的,但可以用来复现问题)。
你需要写一个 document.write 对象:
document.write('<script type="text/javascript" src="file.js" ></script>');
并将其放在您的主要 javascript 文件中
直接是不可能的。您也可以编写一些可以处理的预处理器。
如果我理解正确,那么以下是有助于实现这一目标的事情:
使用一个预处理器,它会运行你的 JS 文件,例如寻找像“@import somefile.js”这样的模式,并将它们替换为实际文件的内容。Nicholas Zakas(雅虎)用 Java 编写了一个这样的库,您可以使用它(http://www.nczonline.net/blog/2009/09/22/introducing-combiner-a-javascriptcss-concatenation-tool/)
如果您使用的是 Ruby on Rails,那么您可以尝试使用 Jammit 资产打包,它使用 assets.yml 配置文件,您可以在其中定义可以包含多个文件的包,然后在您的实际网页中通过包名称引用它们。
尝试使用像RequireJS这样的module加载器或像LabJs这样的脚本加载器,它们能够控制加载顺序并利用并行下载的优势。
JavaScript 目前不提供将 JavaScript 文件包含到另一个类似 CSS ( @import ) 的“本机”方式,但上述所有工具/方式都有助于实现您提到的 DRY 原则。我可以理解,如果您来自服务器端背景,它可能会感觉不直观,但事情就是这样。对于前端开发人员来说,这个问题通常是“部署和打包问题”。
希望能帮助到你。