如何在另一个JavaScript文件中包含JavaScript文件?

JavaScript中是否有类似于@import的JavaScript代码,允许您在另一个JavaScript文件中包含JavaScript文件?

旧版本的JavaScript没有导入,包含或要求,所以已经开发了许多不同的方法来解决这个问题。

但是最近版本的JavaScript有类似ES6模块的标准来导入模块,尽pipe大多数浏览器都不支持这样的模块。 许多使用模块的浏览器应用程序都使用构build和/或转换工具,以便使用具有模块等function的新语法。

ES6模块

请注意,目前,对ES6模块的浏览器支持并不是特别好,但它已经到来了。 根据这个StackOverflow的答案 ,它们在Chrome 60,Firefox 54和MS Edge 15中被支持(但在标志后面),只有Safari 10.1提供支持而没有标志。

因此,您现在仍然需要使用构build和/或转换工具来运行有效的JavaScript,而不需要用户使用这些浏览器版本或启用任何标志。

一旦ES6模块很平常,下面是你将如何使用它们:

 // module.js export function hello() { return "Hello"; } // main.js import {hello} from 'module'; // or './module' let val = hello(); // val is "Hello"; 

Node.js需要

Node.js目前正在使用一个module.exports / require系统。 如果您想要import语法,您可以使用babel进行转储。

 // mymodule.js module.exports = { hello: function() { return "Hello"; } } // server.js const myModule = require('./mymodule'); let val = myModule.hello(); // val is "Hello" 

JavaScript还有其他一些方法可以在不需要预处理的浏览器中包含外部JavaScript内容。

AJAX加载

您可以通过AJAX调用来加载其他脚本,然后使用eval来运行它。 这是最直接的方式,但是由于JavaScript沙箱安全模型,它仅限于您的域。 使用eval也为错误,黑客和安全问题打开了大门。

jQuery加载

jQuery库在一行中提供了加载function:

 $.getScript("my_lovely_script.js", function() { alert("Script loaded but not necessarily executed."); }); 

dynamic脚本加载

您可以添加一个脚本标记与脚本URL到HTML中。 为了避免jQuery的开销,这是一个理想的解决scheme。

该脚本甚至可以驻留在不同的服务器上。 此外,浏览器评估代码。 <script>标签可以注入网页<head> ,也可以在closures</body>标签之前插入。

这是一个如何工作的例子:

 function dynamicallyLoadScript(url) { var script = document.createElement("script"); // Make a script DOM node script.src = url; // Set it's src to the provided URL document.head.appendChild(script); // Add it to the end of the head section of the page (could change 'head' to 'body' to add it to the end of the body section instead) } 

这个函数会在页面的头部结尾添加一个新的<script>标签,其中src属性被设置为作为第一个参数赋给函数的URL。

这两个解决scheme在JavaScript疯狂:dynamic脚本加载中进行了讨论和说明。

检测脚本何时执行

现在,你必须知道一个大问题。 这意味着你远程加载代码 。 现代Web浏览器将加载文件并继续执行当前脚本,因为它们会asynchronous加载所有内容以提高性能。 (这适用于jQuery方法和手动dynamic脚本加载方法。)

这意味着,如果直接使用这些技巧, 在您要求加载之后您将无法在下一行使用新加载的代码 ,因为它仍将加载。

例如: my_lovely_script.js包含MySuperObject

 var js = document.createElement("script"); js.type = "text/javascript"; js.src = jsFilePath; document.body.appendChild(js); var s = new MySuperObject(); Error : MySuperObject is undefined 

然后你重新加载页面F5 。 它的工作原理! 混乱…

那么该怎么办呢?

那么,你可以使用作者在我给你的链接build议的黑客。 总之,对于匆忙的人来说,当脚本被加载时,他使用一个事件来运行一个callback函数。 所以你可以把所有使用远程库的代码放在callback函数中。 例如:

 function loadScript(url, callback) { // Adding the script tag to the head as suggested before var head = document.getElementsByTagName('head')[0]; var script = document.createElement('script'); script.type = 'text/javascript'; script.src = url; // Then bind the event to the callback function. // There are several events for cross browser compatibility. script.onreadystatechange = callback; script.onload = callback; // Fire the loading head.appendChild(script); } 

然后你编写你想使用的代码在脚本加载到lambda函数后 :

 var myPrettyCode = function() { // Here, do whatever you want }; 

那么你运行所有的:

 loadScript("my_lovely_script.js", myPrettyCode); 

请注意,脚本可能在DOM加载之后或之前执行,具体取决于浏览器以及是否包含行script.async = false; 。 一般来说 ,有一篇关于Javascript加载的文章讨论了这个问题。

源代码合并/预处理

正如在这个答案的顶部所提到的,现在许多开发人员在他们的项目中使用了WebPack,Babel或者Gulp等构build/转换工具,使他们能够更好地使用新的语法和支持模块,结合文件,缩小等等。

如果有人正在寻找更先进的东西,试试RequireJS 。 您将获得额外的好处,如依赖关系pipe理,更好的并发性,避免重复(即多次检索脚本)。

您可以将您的JavaScript文件写入“模块”,然后在其他脚本中将其作为依赖关系引用。 或者你可以使用RequireJS作为一个简单的“去得到这个脚本”的解决scheme。

例:

将依赖关系定义为模块:

一些-dependency.js

 define(['lib/dependency1', 'lib/dependency2'], function (d1, d2) { //Your actual script goes here. //The dependent scripts will be fetched if necessary. return libraryObject; //For example, jQuery object }); 

implementation.js是依赖于某个dependency.js的 “主”JavaScript文件

 require(['some-dependency'], function(dependency) { //Your script goes here //some-dependency.js is fetched. //Then your script is executed }); 

摘自GitHub自述文件:

RequireJS加载普通的JavaScript文件以及更多定义的模块。 它针对浏览器内的使用进行了优化,包括Web Worker,但可用于其他JavaScript环境,如Rhino和Node。 它实现了asynchronous模块API。

RequireJS使用纯脚本标签来加载模块/文件,所以它应该允许简单的debugging。 它可以简单地用来加载现有的JavaScript文件,所以你可以把它添加到你现有的项目中,而不必重写你的JavaScript文件。

实际上一种不是asynchronous加载JavaScript文件的方法,所以你可以在加载后使用新加载的文件中包含的函数,我认为它可以在所有浏览器中运行。

您需要在页面的<head>元素上使用jQuery.append() ,即:

 $("head").append('<script type="text/javascript" src="' + script + '"></script>'); 

但是,这种方法也存在一个问题:如果在导入的JavaScript文件中发生错误, Firebug (以及Firefox错误控制台和Chrome开发者工具 )将错误地报告它的位置,如果使用Firebug跟踪,这是一个大问题JavaScript错误很多(我做)。 由于某种原因,Firebug并不知道新加载的文件,所以如果该文件发生错误,它会报告它发生在您的主HTML文件中,并且您将无法find错误的真正原因。

但是,如果这不是你的问题,那么这种方法应该工作。

我实际上已经写了一个叫做$ .import_js()的jQuery插件,它使用了这个方法:

 (function($) { /* * $.import_js() helper (for JavaScript importing within JavaScript code). */ var import_js_imported = []; $.extend(true, { import_js : function(script) { var found = false; for (var i = 0; i < import_js_imported.length; i++) if (import_js_imported[i] == script) { found = true; break; } if (found == false) { $("head").append('<script type="text/javascript" src="' + script + '"></script>'); import_js_imported.push(script); } } }); })(jQuery); 

所以你需要做的是导入JavaScript:

$ .import_js( '/ path_to_project /脚本/ somefunctions.js');

我也在http://www.kipras.com/dev/import_js_test/上做了一个简单的testing。;

它在main HTML中包含一个main.js文件,然后main.js的脚本使用$.import_js()来导入一个名为included.js文件,该文件定义了这个函数:

 function hello() { alert("Hello world!"); } 

在包含included.js ,调用hello()函数,并获得警报。

(这个答案是为了回应e-satis的评论)。

另一种方式,在我看来是更清洁,是做一个同步的Ajax请求,而不是使用<script>标记。 这也是Node.js如何处理的。

这里是一个使用jQuery的例子:

 function require(script) { $.ajax({ url: script, dataType: "script", async: false, // <-- This is the key success: function () { // all good... }, error: function () { throw new Error("Could not load script " + script); } }); } 

然后,您可以像使用include一样在代码中使用它:

 require("/scripts/subscript.js"); 

并且能够从下一行中所需的脚本中调用一个函数:

 subscript.doSomethingCool(); 

对你来说有个好消息。 很快,您将可以轻松加载JavaScript代码。 它将成为导入JavaScript代码模块的标准方式,并将成为JavaScript核心本身的一部分。

你只需import cond from 'cond.js';编写import cond from 'cond.js'; 从文件cond.js加载一个名为cond的macros。

所以你不需要依赖任何JavaScript框架,也不需要明确地进行Ajax调用。

参考:

  • 静态模块分辨率

  • 模块装载机

可以dynamic生成一个JavaScript标记并将其附加到其他JavaScript代码中的HTML文档中。 这将加载目标JavaScript文件。

 function includeJs(jsFilePath) { var js = document.createElement("script"); js.type = "text/javascript"; js.src = jsFilePath; document.body.appendChild(js); } includeJs("/path/to/some/file.js"); 

语句import在ECMAScript 6中。

句法

 import name from "module-name"; import { member } from "module-name"; import { member as alias } from "module-name"; import { member1 , member2 } from "module-name"; import { member1 , member2 as alias2 , [...] } from "module-name"; import name , { member [ , [...] ] } from "module-name"; import "module-name" as name; 

也许你可以使用我在这个页面中find的这个函数如何在一个JavaScript文件中包含一个JavaScript文件?

 function include(filename) { var head = document.getElementsByTagName('head')[0]; var script = document.createElement('script'); script.src = filename; script.type = 'text/javascript'; head.appendChild(script) } 

这是一个没有jQuery同步版本:

 function myRequire( url ) { var ajax = new XMLHttpRequest(); ajax.open( 'GET', url, false ); // <-- the 'false' makes it synchronous ajax.onreadystatechange = function () { var script = ajax.response || ajax.responseText; if (ajax.readyState === 4) { switch( ajax.status) { case 200: eval.apply( window, [script] ); console.log("script loaded: ", url); break; default: console.log("ERROR: script not loaded: ", url); } } }; ajax.send(null); } 

请注意,要获得这个跨域的工作,服务器将需要在响应中设置allow-origin

我只写了这个JavaScript代码(使用DOM操作的原型 ):

 var require = (function() { var _required = {}; return (function(url, callback) { if (typeof url == 'object') { // We've (hopefully) got an array: time to chain! if (url.length > 1) { // Load the nth file as soon as everything up to the // n-1th one is done. require(url.slice(0, url.length - 1), function() { require(url[url.length - 1], callback); }); } else if (url.length == 1) { require(url[0], callback); } return; } if (typeof _required[url] == 'undefined') { // Haven't loaded this URL yet; gogogo! _required[url] = []; var script = new Element('script', { src: url, type: 'text/javascript' }); script.observe('load', function() { console.log("script " + url + " loaded."); _required[url].each(function(cb) { cb.call(); // TODO: does this execute in the right context? }); _required[url] = true; }); $$('head')[0].insert(script); } else if (typeof _required[url] == 'boolean') { // We already loaded the thing, so go ahead. if (callback) { callback.call(); } return; } if (callback) { _required[url].push(callback); } }); })(); 

用法:

 <script src="prototype.js"></script> <script src="require.js"></script> <script> require(['foo.js','bar.js'], function () { /* Use foo.js and bar.js here */ }); </script> 

要点: http : //gist.github.com/284442 。

我认为这也许是JavaScript最大的弱点。 多年来,依赖追踪导致我无法解决问题。 无论如何,它似乎唯一实际的解决scheme是使用脚本包括在HTML文件中,从而可怕地使您的JavaScript代码依赖于用户,包括您需要的来源,使重用不友好。

对不起,如果这是演讲的话;)这是我的(坏)习惯,但我想说明一下。

这个问题和networking上的所有其他内容一样,都是JavaScript的历史。 它的devise目的并不在于它在今天被广泛使用。 网景公司制作了一种语言,可以让你控制一些东西,但是他们并没有设想它被广泛用于如此多的东西,因为它被放置到现在,并且出于某种原因,它从那里扩展,而没有解决一些根本的问题原战略的弱点。

当然不是一个人 HTML不是为现代网页devise的; 它被devise成expression文档逻辑的一种方式,以便读者(现代世界中的浏览器)能够以系统能力范围内的适用forms显示这个文档,并且需要花费数年时间才能find一个解决scheme比MS和Netscape的黑客)来。 CSS解决了这个问题,但是很长一段时间,甚至更长的时间让人们使用它,而不是已有的BAD技术。 它发生虽然,赞美是。

希望JavaScript(特别是现在是标准的一部分)将会发展成像世界上所有其他(现存的)编程语言一样采用适当的模块化(以及其他一些东西)的概念,这种愚蠢将会消失。 在那之前,你只是不得不喜欢它,我害怕。

下面是Facebook如何为其无处不在的Likebutton提供的一般化版本:

 <script> var firstScript = document.getElementsByTagName('script')[0], js = document.createElement('script'); js.src = 'ajax/libs/Snowstorm/20131208/snowstorm-min.js'; js.onload = function () { // do stuff with your dynamically loaded script snowStorm.snowColor = '#99ccff'; }; firstScript.parentNode.insertBefore(js, firstScript); </script> 

您还可以使用PHP组装您的脚本:

文件main.js.php

 <?php header('Content-type:text/javascript; charset=utf-8'); include_once("foo.js.php"); include_once("bar.js.php"); ?> // Main JavaScript code goes here 

这里显示的大部分解决scheme都意味着dynamic加载。 我正在寻找一个编译器,将所有依赖的文件组合成一个输出文件。 与Less / Sass预处理器一样,处理CSS @import at-rule。 由于我没有发现任何这样的体面,我写了一个简单的工具来解决这个问题。

所以这里是编译器, https://github.com/dsheiko/jsic ,安全地replace$import("file-path")与请求的文件内容。 这是相应的Grunt插件: https : //github.com/dsheiko/grunt-jsic 。

在jQuery master分支上,他们简单地将primefaces源文件连接成一个以intro.js开始并以intro.js结束的outtro.js 。 这不适合我,因为它没有提供源代码devise的灵活性。 看看它如何与jsic一起工作:

SRC / main.js

 var foo = $import("./Form/Input/Tel"); 

SRC /表格/input/ Tel.js

 function() { return { prop: "", method: function(){} } } 

现在我们可以运行编译器了:

 node jsic.js src/main.js build/mail.js 

并获得组合文件

build立/ main.js

 var foo = function() { return { prop: "", method: function(){} } }; 

如果你想用纯JavaScript,你可以使用document.write。

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

如果您使用jQuery库,则可以使用$ .getScript方法 。

 $.getScript("another_script.js"); 

这应该做的:

 xhr = new XMLHttpRequest(); xhr.open("GET", "/soap/ajax/11.0/connection.js", false); xhr.send(); eval(xhr.responseText); 

或者,不要在运行时包含,请在上传之前使用脚本进行连接。

我使用链轮 (我不知道是否有其他人)。 您可以在不同的文件中构buildJavaScript代码,并将包含由Sprockets引擎处理的注释包含在内。 对于开发,你可以包括文件顺序,然后生产合并它们…

也可以看看:

  • Sprockets介绍:JavaScript依赖pipe理和连接

如果要加载JavaScript文件的意图是使用导入/包含文件中的函数 ,则还可以定义一个全局对象并将这些函数设置为对象项。 例如:

global.js

 A = {}; 

file1.js

 A.func1 = function() { console.log("func1"); } 

file2.js

 A.func2 = function() { console.log("func2"); } 

main.js

 A.func1(); A.func2(); 

当您将脚本包含在HTML文件中时,您只需要小心。 顺序应该如下所示:

 <head> <script type="text/javascript" src="global.js"></script> <script type="text/javascript" src="file1.js"></script> <script type="text/javascript" src="file2.js"></script> <script type="text/javascript" src="main.js"></script> </head> 

如果您正在使用Web Workers并希望在工作人员的范围中包含其他脚本,则向head标签添加脚本等的其他答案将不适用于您。

幸运的是, Web Workers拥有自己的importScripts函数 ,它是Web Worker范围内的一个全局函数,是浏览器本身的本身,因为它是规范的一部分 。

或者, 作为你的问题的第二高投票答案突出显示 , RequireJS还可以处理在Web工作人员(可能调用importScripts本身,但有一些其他有用的function)内的脚本。

我写了一个简单的模块,可以自动完成在JavaScript中导入/包括模块脚本的工作。 有关代码的详细说明,请参阅博客文章JavaScript require / import / include模块

 // ----- USAGE ----- require('ivar.util.string'); require('ivar.net.*'); require('ivar/util/array.js'); require('http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js'); ready(function(){ //Do something when required scripts are loaded }); //-------------------- var _rmod = _rmod || {}; //Require module namespace _rmod.LOADED = false; _rmod.on_ready_fn_stack = []; _rmod.libpath = ''; _rmod.imported = {}; _rmod.loading = { scripts: {}, length: 0 }; _rmod.findScriptPath = function(script_name) { var script_elems = document.getElementsByTagName('script'); for (var i = 0; i < script_elems.length; i++) { if (script_elems[i].src.endsWith(script_name)) { var href = window.location.href; href = href.substring(0, href.lastIndexOf('/')); var url = script_elems[i].src.substring(0, script_elems[i].length - script_name.length); return url.substring(href.length+1, url.length); } } return ''; }; _rmod.libpath = _rmod.findScriptPath('script.js'); //Path of your main script used to mark //the root directory of your library, any library. _rmod.injectScript = function(script_name, uri, callback, prepare) { if(!prepare) prepare(script_name, uri); var script_elem = document.createElement('script'); script_elem.type = 'text/javascript'; script_elem.title = script_name; script_elem.src = uri; script_elem.async = true; script_elem.defer = false; if(!callback) script_elem.onload = function() { callback(script_name, uri); }; document.getElementsByTagName('head')[0].appendChild(script_elem); }; _rmod.requirePrepare = function(script_name, uri) { _rmod.loading.scripts[script_name] = uri; _rmod.loading.length++; }; _rmod.requireCallback = function(script_name, uri) { _rmod.loading.length--; delete _rmod.loading.scripts[script_name]; _rmod.imported[script_name] = uri; if(_rmod.loading.length == 0) _rmod.onReady(); }; _rmod.onReady = function() { if (!_rmod.LOADED) { for (var i = 0; i < _rmod.on_ready_fn_stack.length; i++){ _rmod.on_ready_fn_stack[i](); }); _rmod.LOADED = true; } }; _.rmod = namespaceToUri = function(script_name, url) { var np = script_name.split('.'); if (np.getLast() === '*') { np.pop(); np.push('_all'); } if(!url) url = ''; script_name = np.join('.'); return url + np.join('/')+'.js'; }; //You can rename based on your liking. I chose require, but it //can be called include or anything else that is easy for you //to remember or write, except "import", because it is reserved //for future use. var require = function(script_name) { var uri = ''; if (script_name.indexOf('/') > -1) { uri = script_name; var lastSlash = uri.lastIndexOf('/'); script_name = uri.substring(lastSlash+1, uri.length); } else { uri = _rmod.namespaceToUri(script_name, ivar._private.libpath); } if (!_rmod.loading.scripts.hasOwnProperty(script_name) && !_rmod.imported.hasOwnProperty(script_name)) { _rmod.injectScript(script_name, uri, _rmod.requireCallback, _rmod.requirePrepare); } }; var ready = function(fn) { _rmod.on_ready_fn_stack.push(fn); }; 
 var js = document.createElement("script"); js.type = "text/javascript"; js.src = jsFilePath; document.body.appendChild(js); 

I had a simple issue, but I was baffled by responses to this question.

I had to use a variable (myVar1) defined in one JavaScript file (myvariables.js) in another JavaScript file (main.js).

For this I did as below:

Loaded the JavaScript code in the HTML file, in the correct order, myvariables.js first, then main.js:

 <html> <body onload="bodyReady();" > <script src="myvariables.js" > </script> <script src="main.js" > </script> <!-- Some other code --> </body> </html> 

File: myvariables.js

 var myVar1 = "I am variable from myvariables.js"; 

File: main.js

 // ... function bodyReady() { // ... alert (myVar1); // This shows "I am variable from myvariables.js", which I needed // ... } // ... 

As you saw, I had use a variable in one JavaScript file in another JavaScript file, but I didn't need to include one in another. I just needed to ensure that the first JavaScript file loaded before the second JavaScript file, and, the first JavaScript file's variables are accessible in the second JavaScript file, automatically.

This saved my day. 我希望这有帮助。

There is also Head.js . It is very easy to deal with:

 head.load("js/jquery.min.js", "js/jquery.someplugin.js", "js/jquery.someplugin.css", function() { alert("Everything is ok!"); }); 

As you see, it's easier than Require.js and as convenient as jQuery's $.getScript method. It also has some advanced features, like conditional loading, feature detection and much more .

The @import syntax for achieving CSS-like JavaScript importing is possible using a tool such as Mixture via their special .mix file type (see here ). I imagine the application simply uses one of the aforementioned methods interally, though I don't know.

From the Mixture documentation on .mix files:

Mix files are simply .js or .css files with .mix. in the file name. A mix file simply extends the functionality of a normal style or script file and allows you to import and combine.

Here's an example .mix file that combines multiple .js files into one:

 // scripts-global.mix.js // Plugins - Global @import "global-plugins/headroom.js"; @import "global-plugins/retina-1.1.0.js"; @import "global-plugins/isotope.js"; @import "global-plugins/jquery.fitvids.js"; 

Mixture outputs this as scripts-global.js and also as a minified version ( scripts-global.min.js ).

Note: I'm not in any way affiliated with Mixture, other than using it as a front-end development tool. I came across this question upon seeing a .mix JavaScript file in action (in one of the Mixture boilerplates) and being a bit confused by it ("you can do this?" I thought to myself). Then I realized that it was an application-specific file type (somewhat disappointing, agreed). Nevertheless, figured the knowledge might be helpful for others.

UPDATE : Mixture is now free .

I came to this question because I was looking for a simple way to maintain a collection of useful JavaScript plugins. After seeing some of the solutions here, I came up with this:

1) Set up a file called "plugins.js" (or extentions.js or what have you). Keep your plugin files together with that one master file.

2) plugins.js will have an array called "pluginNames[]" that we will iterate over each(), then append a tag to the head for each plugin

 //set array to be updated when we add or remove plugin files var pluginNames = ["lettering", "fittext", "butterjam", etc.]; //one script tag for each plugin $.each(pluginNames, function(){ $('head').append('<script src="js/plugins/' + this + '.js"></script>'); }); 

3) manually call just the one file in your head:
<script src="js/plugins/plugins.js"></script>

UPDATE: I found that even though all of the plugins were getting dropped into the head tag the way they ought to, they weren't always being run by the browser when you click into the page or refresh.

I found it's more reliable to just write the script tags in a PHP include. You only have to write it once and that's just as much work as calling the plugin using JavaScript.

I have created a function that will allow you to use similar verbiage to C#/Java to include a JavaScript file. I've tested it a little bit even from inside of another JavaScript file and it seems to work. It does require jQuery though for a bit of "magic" at the end.

I put this code in a file at the root of my script directory (I named it global.js , but you can use whatever you want. Unless I'm mistaken this and jQuery should be the only required scripts on a given page. Keep in mind this is largely untested beyond some basic usage, so there may or may not be any issues with the way I've done it; use at your own risk yadda yadda I am not responsible if you screw anything up yadda yadda:

 /** * @fileoverview This file stores global functions that are required by other libraries. */ if (typeof(jQuery) === 'undefined') { throw 'jQuery is required.'; } /** Defines the base script directory that all .js files are assumed to be organized under. */ var BASE_DIR = 'js/'; /** * Loads the specified file, outputting it to the <head> HTMLElement. * * This method mimics the use of using in C# or import in Java, allowing * JavaScript files to "load" other JavaScript files that they depend on * using a familiar syntax. * * This method assumes all scripts are under a directory at the root and will * append the .js file extension automatically. * * @param {string} file A file path to load using C#/Java "dot" syntax. * * Example Usage: * imports('core.utils.extensions'); * This will output: <script type="text/javascript" src="/js/core/utils/extensions.js"></script> */ function imports(file) { var fileName = file.substr(file.lastIndexOf('.') + 1, file.length); // Convert PascalCase name to underscore_separated_name var regex = new RegExp(/([AZ])/g); if (regex.test(fileName)) { var separated = fileName.replace(regex, ",$1").replace(',', ''); fileName = separated.replace(/[,]/g, '_'); } // Remove the original JavaScript file name to replace with underscore version file = file.substr(0, file.lastIndexOf('.')); // Convert the dot syntax to directory syntax to actually load the file if (file.indexOf('.') > 0) { file = file.replace(/[.]/g, '/'); } var src = BASE_DIR + file + '/' + fileName.toLowerCase() + '.js'; var script = document.createElement('script'); script.type = 'text/javascript'; script.src = src; $('head').find('script:last').append(script); } 

Better use the jQuery way. To delay the ready event, first call $.holdReady(true) . Example ( source ):

 $.holdReady(true); $.getScript("myplugin.js", function() { $.holdReady(false); }); 

This script will add a JavaScript file to the top of any other <script> tag:

 (function () { var li = document.createElement('script'); li.type = 'text/javascript'; li.src= "http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"; li.async=true; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(li, s); })(); 

My usual method is:

 var require = function (src, cb) { cb = cb || function () {}; var newScriptTag = document.createElement('script'), firstScriptTag = document.getElementsByTagName('script')[0]; newScriptTag.src = src; newScriptTag.async = true; newScriptTag.onload = newScriptTag.onreadystatechange = function () { (!this.readyState || this.readyState === 'loaded' || this.readyState === 'complete') && (cb()); }; firstScriptTag.parentNode.insertBefore(newScriptTag, firstScriptTag); } 

It works great and uses no page-reloads for me. I've tried the AJAX method (one of the other answers) but it doesn't seem to work as nicely for me.

Here's an explanation of how the code works for those that are curious: essentially, it creates a new script tag (after the first one) of the URL. It sets it to asynchronous mode so it doesn't block the rest of the code, but calls a callback when the readyState (the state of the content to be loaded) changes to 'loaded'.

Here is a Grunt plugin allowing you to use @import "path/to/file.js"; syntax in any file including JavaScript files. It can be paired with uglify or watch or any other plugin.

It can be installed with npm install: https://npmjs.org/package/grunt-import