Javascript 如何在另一个js文件中包含js文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4634644/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to include js file in another js file?
提问by Aditya Shukla
How can I include a js file into another js file , so as to stick to the DRY principleand avoid duplication of code.
如何将一个js文件包含到另一个js文件中,以坚持DRY原则,避免代码重复。
回答by Matt Ball
You can only include a script file in an HTML page, not in another script file. That said, you canwrite JavaScript which loads your "included" script into the same page:
您只能在 HTML 页面中包含脚本文件,而不能在另一个脚本文件中包含。也就是说,您可以编写 JavaScript,将“包含的”脚本加载到同一页面中:
var imported = document.createElement('script');
imported.src = '/path/to/imported/script';
document.head.appendChild(imported);
There's a good chance your code depends on your "included" script, however, in which case it may fail because the browser will load the "imported" script asynchronously. Your best bet will be to simply use a third-party library like jQuery or YUI, which solves this problem for you.
您的代码很可能取决于您的“包含”脚本,但是,在这种情况下,它可能会失败,因为浏览器将异步加载“导入”脚本。您最好的选择是简单地使用第三方库,如 jQuery 或 YUI,它会为您解决这个问题。
// jQuery
$.getScript('/path/to/imported/script.js', function()
{
// script is now loaded and executed.
// put your dependent JS here.
});
回答by Oleg
I disagree with the document.write
technique (see suggestion of Vahan Margaryan). I like document.getElementsByTagName('head')[0].appendChild(...)
(see suggestion of Matt Ball), but there is one important issue: the script execution order.
我不同意这种document.write
技术(见Vahan Margaryan 的建议)。我喜欢document.getElementsByTagName('head')[0].appendChild(...)
(参见Matt Ball 的建议),但有一个重要问题:脚本执行顺序。
Recently, I have spent a lot of time reproducing one similar issue, and even the well-known jQuery plugin uses the same technique (see src here) to load the files, but others have also reported the issue. Imagine you have JavaScript library which consists of many scripts, and one loader.js
loads all the parts. Some parts are dependent on one another. Imagine you include another main.js
script per <script>
which uses the objects from loader.js
immediately after the loader.js
. The issue was that sometimes main.js
is executed before all the scripts are loaded by loader.js
. The usage of $(document).ready(function () {/*code here*/});
inside of main.js
script does not help. The usage of cascading onload
event handler in the loader.js
will make the script loading sequential instead of parallel, and will make it difficult to use main.js
script, which should just be an include somewhere after loader.js
.
最近,我花了很多时间重现一个类似的问题,甚至著名的 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
.
By reproducing the issue in my environment, I can see that **the order of execution of the scripts in Internet Explorer 8 can differ in the inclusion of the JavaScript*. It is a very difficult issue if you need include scripts that are dependent on one another. The issue is described in Loading Javascript files in parallel, and the suggested workaround is to use document.writeln
:
通过在我的环境中重现该问题,我可以看到 **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>");
So in the case of "the scripts are downloaded in parallel but executed in the order they're written to the page", after changing from document.getElementsByTagName('head')[0].appendChild(...)
technique to document.writeln
, I had not seen the issue anymore.
因此,在“脚本并行下载但按写入页面的顺序执行”的情况下,从document.getElementsByTagName('head')[0].appendChild(...)
技术更改为 后document.writeln
,我再也没有看到这个问题。
So I recommend that you use document.writeln
.
所以我建议你使用document.writeln
.
UPDATED: If somebody is interested, they can try to load (and reload) the pagein Internet Explorer (the page uses the document.getElementsByTagName('head')[0].appendChild(...)
technique), and then compare with the fixed versionused document.writeln
. (The code of the page is relatively dirty and is not from me, but it can be used to reproduce the issue).
已更新:如果有人有兴趣,他们可以尝试负载(和重装)的页面在Internet Explorer(页面使用的document.getElementsByTagName('head')[0].appendChild(...)
技术),然后用比较固定的版本使用document.writeln
。(页面代码比较脏,不是我写的,但可以用来复现问题)。
回答by Vahan Margaryan
You need to write a document.write object:
你需要写一个 document.write 对象:
document.write('<script type="text/javascript" src="file.js" ></script>');
and place it in your main javascript file
并将其放在您的主要 javascript 文件中
回答by Arnab
It is not possible directly. You may as well write some preprocessor which can handle that.
直接是不可能的。您也可以编写一些可以处理的预处理器。
If I understand it correctly then below are the things that can be helpful to achieve that:
如果我理解正确,那么以下是有助于实现这一目标的事情:
Use a pre-processor which will run through your JS files for example looking for patterns like "@import somefile.js" and replace them with the content of the actual file. Nicholas Zakas(Yahoo) wrote one such library in Java which you can use (http://www.nczonline.net/blog/2009/09/22/introducing-combiner-a-javascriptcss-concatenation-tool/)
If you are using Ruby on Rails then you can give Jammit asset packaging a try, it uses assets.yml configuration file where you can define your packages which can contain multiple files and then refer them in your actual webpage by the package name.
Try using a module loader like RequireJSor a script loader like LabJswith the ability to control the loading sequence as well as taking advantage of parallel downloading.
使用一个预处理器,它会运行你的 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 配置文件,您可以在其中定义可以包含多个文件的包,然后在您的实际网页中通过包名称引用它们。
JavaScript currently does not provide a "native" way of including a JavaScript file into another like CSS ( @import ), but all the above mentioned tools/ways can be helpful to achieve the DRY principle you mentioned. I can understand that it may not feel intuitive if you are from a Server-side background but this is the way things are. For front-end developers this problem is typically a "deployment and packaging issue".
JavaScript 目前不提供将 JavaScript 文件包含到另一个类似 CSS ( @import ) 的“本机”方式,但上述所有工具/方式都有助于实现您提到的 DRY 原则。我可以理解,如果您来自服务器端背景,它可能会感觉不直观,但事情就是这样。对于前端开发人员来说,这个问题通常是“部署和打包问题”。
Hope it helps.
希望能帮助到你。