I'm releasing v1.0 of using.js which introduces a new way of declaring dependency scripts in Javscript.
http://www.jondavis.net/codeprojects/using.js/
The goals of using.js are to:
-
Seperate script dependencies from HTML markup (let the script framework figure out the dependencies it needs, not the designer).
-
Make script referencing as simple and easy as possible (no need to manage the HTML files)
-
Lazy load the scripts and not load them until and unless they are actually needed at runtime
The way it works is simple. Add a <script src="using.js"> reference to the <head> tag:
<html>
<head>
<script type="text/javascript" language="javascript" src="using.js"></script>
<script type="text/javascript" language="javascript">
// your script here
</script>
</head>
<body> .. </body>
</html>
Then in your script, register your potential dependencies. (These will not get loaded until they get used!)
using.register("jquery", "/scripts/jquery-1.2.3.js");
Finally, when you need to begin invoking some functionality that requires your dependency invoke using():
using("jquery"); // loads jQuery and de-registers jQuery from using
$("a").css("text-decoration", "none");
using("jquery"); // redundant calls to using() won't repeat fetch of jQuery because jquery was de-registered from using
$("a").css("color", "green");
Note that this is only synchronous if the global value of using.wait is 0 (the default). You can reference scripts on external domains if you precede the URL in the using.register() statement with true and/or with an integer milliseconds value, or if you set the global using.wait to something like 500 or 1000, but then you must write your dependency usage scripts with a callback. (UPDATE: v1.0.1: Simply providing a callback will also make the load asynchronous.) No problem, here's how it's done:
using.register("jquery", true, "http://cachefile.net/scripts/jquery-1.2.3.js");
using("jquery", function() {
$("a").css("text-decoration", "none"); //async callback
});
Oh, and by the way, using.register() supports multiple dependency script URLs.
using.register('multi', // 'multi' is the name
'/scripts/dep1.js', // dep1.js is the first dependency
'/scripts/dep2.js' // dep2.js is the secon dependency
);
UPDATE: I just mostly rewrote using.js. Now with v1.1 you can now add subdependencies, like so:
using.register('jquery-blockUI', true,
'http://cachefile.net/scripts/jquery/plugins/blockUI/2.02/jquery.blockUI.js'
).requires('jquery');
Basically what the new .requires() functionality will do is when you invoke using('jquery-blockUI'); it will also load up jquery first.
UPDATE 2: With v1.2 I've added several new additional touches. Now you don't *have* to declare your subdependencies with using.register(), you can just say:
using('jquery', 'jquery-blockUI', function() {
$.blockUI();
});
This assumes that jQuery and blockUI have both been registered, the latter without the .requires('jquery') invocation.
That said, though, you don't even have to call .register anymore if you don't want to:
using('url(http://cachefile.net/scripts/jquery/1.2.3/jquery-1.2.3.js)', function() {
alert($.fn.jquery);
});
There are also two new features that *should* work but I haven't written tests yet:
-
using.register([json object]); // see using.prototype.Registration
-
Registration chaining:
-
using
.register("myScript", "/myscript.js")
.register("myOtherScript", "/myotherscript.js").requires('myScript')
.register("bob's script", "/bob.js");
UPDATE 3: v1.3 fixes the using('url(..')) functionality so that a script loaded this way is remembered so that is not fetched again if the same URL is referenced in the same way again. This is the reverse of the using.register() behavior, where if a script is loaded its registration is "forgotten". Also made sure that multiple script URLs listed in using('url(..)', 'url(..)'), function(){}); is supported correctly.
If for some strange reason you want the script at the same URL to be re-fetched, try this unsupported hack that might not be available tomorrow:
using.__durls['http://my/url.js'] = undefined;
UPDATE 3.1: V1.3.1 should hopefully fix the "not enough arguments" error that some Firefox users have been having. I was never able to reproduce this, but I did discover after doing some research that Firefox supposedly expects null to be passed into xhr.send(). I guess some systems suffered from this while I didn't. At any rate, I'm passing null now.
If you have bug reports or suggestions, please post comments here or e-mail me at jon@jondavis.net.