An asynchronous, dependency-resolving library framework for JavaScript.
This framework allows you to create your own hybrid library for your own uses. This is a generic version of what our company calls "Clarity."
... you can push "commands," or what ASDR has called work objects, into the library as a queue before the library script is downloaded and executed. Once the script is done loading, the work objects are procesesed and the API remains the same.
... your work objects specify which modules you want to use. The script for these modules are pre-bundled into the main library, but are unexecuted until another module or work object requires a given module.
There's no AJAX'ing for additional resources, so it's super fast. Your entire library (modules, template, and styles) is in a single file that can be cached, CDN'd, minified, gzipped, and then used throughout your network.
ASDR libraries can co-exist with any other framework or code-base. All modules should not escape outside the ASDR library. The entire library is namespaced inside a single global variable of your choosing. Since you create the modules yourself, you can use multiple versions of the same library on the same page as separate modules.
Got old code using jQuery 1.2, but you want to use jQuery 2 for everything you are writing now? Create a jQuery 2.0 ASDR module, and now they don't conflict!
The same file is used in each context, so all code is on all sites.
It's good to be able to have multiple versions of jQuery on the page... but you really shouldn't make your customers download jQuery multiple times.
The library is not pre-processed on request, so no request-specific code can exist.
ASDR libraries are "compiled" by the make.sh
script. This script handles the proper execution order, minifying, and mashing.
./make.sh [namespace] [min|src] > [library file]
namespace
can be any JavaScript friendly variable name.
min|src
specifies which type of script you would like to return.
make.sh
outputs to STDOUT, so you will need to redirect output via >
to the library file
you want.
./make.sh TESTING min > /var/www/scripts/testing.js
/var/www/scripts/testing.js
will be the compiled minified version of your ASDR library exposed as TESTING (window.TESTING
) in the JavaScript global scope.
Include something like this in the head of your document.
<script>
(function(w, d, c, t){
w[c] = w[c] || [];
var n = d.createElement(t), s = d.getElementsByTagName(t)[0];
n.async = true; n.src = '//the.location.of.your.script.com/script.js';
s.parentNode.insertBefore(n, s);
})(window, document, 'YOURLIBRARY', 'script');
</script>
The primary way for front-end code to use your ASDR library is through work objects.
A work object consists of 2 properties:
{
use: ['moduleA', 'moduleB'],
run: function(moduleA, moduleB){}
}
use
: an array of module names your implementation code requires.run
: a closure your implementation code resides in, gets executed once your ASDR library is ready and all dependencies. Your specified dependencies are exposed as whichever variables you would like inside your closure, in order of inclusion.
Work object typically get passes as an argument to your ASDR library's push()
method.
YOURLIBRARY.push({
use: ['moduleA', 'moduleB'],
run: function(moduleA, moduleB){
console.log('do work!');
}
});
There's 3 types of items that can be bundled by the make.sh
script to make your ASDR library. make.sh
looks for each in a specific directory in ./src
.
Modules are the main item type you will be creating for your ASDR library. Place your modules in ./src/modules
.
Modules are comprised of various pieces of information that are passed to the ASDR library function provide
.
__LIBRARY_NAME__.provide('module_name', ['depA', 'depB'], function(depA, depB){ return module_value; });
__LIBRARY_NAME__
: A placeholder string that gets replaced with your specified namespace bymake.sh
. You should not have to change this.module_name
: The name other modules and work-objects will refer to this module as once it's registered.['depA', 'depB']
: An array of names of other modules this module requires to function. If this module has no dependencies, pass an empty array ([]
).function(depA, depB){}
: The closure your module code resides in. This code only gets executed when another module or work object specifies this module as a dependency. Each dependency you specify in the previous argument gets their value exposed as whatever argument name you specify, in order of inclusion.return module_value;
: Each module should return a value so that other modules and work objects can receieve your code as arguments to their closures.
ASDR stores all calls to provide without executing them. Once another module or work object that requires your module is executed, your module code is executed. Your module's code is executed once, cached internally by ASDR, and then passed by reference in most cases. A good pattern is to return a constructor function with your module, and then initialize a new instance within your implementation code.
__LIBRARY_NAME__.provide('bluemaker', ['jquery', 'underscore'], function($, _){
var BlueMaker = function BlueMaker (element) {
this.$element = $(element);
};
BlueMaker.prototype.blues = ['blue', 'lightblue', 'cornflowerblue', 'steelblue'];
BlueMaker.prototype.makeBlue = function makeBlue () {
this.$element.css('color', this.blues[_.random(0, this.blues.length-1]));
};
return BlueMaker;
});