Abstracting a bit my bookmarklet for injecting jQuery, I’ve come to this one where you can orderly require needed scripts before executing a given payload.

javascript:(function () {

    var debug = !false;
    var requested = false;

    orderly(
        require_jQuery('1.8.3', 'j'),
        require_SimpleModal('j'),
        function() {
            payload(window.j);
        }
    );

    function payload(jQuery) {
        jQuery(function($) {
            $('body').click(function() {
                $('span:first').modal({
                    overlayClose: true,
                    opacity: 80,
                    overlayCss: {backgroundColor: "#000"},
                    maxHeight: 480,
                    maxWidth: 640,
                    containerCss:{
                        backgroundColor:"#fff",
                        borderColor:"#fff",
                        padding:20
                    }
                });
            });
        });
    }

    function require_jQuery(version, symbol) {
        return {
            url: 'http://ajax.googleapis.com/ajax/libs/jquery/' + version + '/jquery.min.js',
            is_loaded: function() {
                return !requested && typeof window[symbol] != 'undefined' && window[symbol].fn.jquery == version
                    ||  requested && typeof window.jQuery  != 'undefined' && window.jQuery.fn.jquery  == version;
            },
            before: function() {
                window.oldJQuery = window.jQuery;
                window.jQuery = window.undefined;
            },
            success: function() {
                jQuery.noConflict();
                window[symbol] = jQuery;
                console.info('jQuery ' + jQuery.fn.jquery + ' has been injected. (as "' + symbol + '")');
            },
            ensure: function () {
                window.jQuery = window.oldJQuery;
            }
        };
    }

    function require_SimpleModal(jQuerySymbol) {
        return {
            url: 'http://cdn.jsdelivr.net/simplemodal/1.4.2/jquery.simplemodal.1.4.2.min.js',
            is_loaded: function() {
                return !requested && typeof window[jQuerySymbol].modal != 'undefined'
                    ||  requested && typeof window.jQuery.modal        != 'undefined';
            },
            before: function() {
                window.oldJQuery = window.jQuery;
                window.jQuery = window[jQuerySymbol];
            },
            ensure: function () {
                window.jQuery = window.oldJQuery;
            }
        };
    }

    function orderly(i) {
        var stuff = Array.prototype.slice.call(arguments);
        if (typeof i === 'number') {
            stuff.shift();
        }
        else {
            i = 0;
        }
        if (i == stuff.length) return;

        console_log('orderly ' + i);
        switch (typeof stuff[i]) {
            case 'string':
                break;
            case 'function':
                stuff[i]();
                orderly.apply(null, [i+1].concat(stuff));
                break;
            case 'object':
                load_script(stuff, i);
                break;
            default:
                throw 'Expected a valid argument (' + i + ')';
                break;
        }
    }

    function load_script(stuff, i) {
        var current = stuff[i];
        var url = current.url;
        console_log('load_script: request for ' + url);

        requested = false;
        var is_loaded = current.is_loaded;
        if (is_loaded()) {
            console_log('load_script: already available');
            orderly.apply(null, [i+1].concat(stuff));
            return;
        }
        var before = current.before;
        var success = function() {
            call_function(current.success);
            call_function(current.ensure);
            orderly.apply(null, [i+1].concat(stuff));
        };
        var failure = function() {
            call_function(current.failure);
            call_function(current.ensure);
        };
        call_function(before);

        console_log('load_script: requesting');
        var s = document.createElement('script');
        s.setAttribute('src', url);
        document.getElementsByTagName('head')[0].appendChild(s);

        requested = true;
        var time = 0;
        var id = setInterval(function () {
            console_log('load_script: retry #' + time);
            if (is_loaded()) {
                clearInterval(id);
                console_log('load_script: done');
                success();
                return;
            }
            ++time;
            if (time == 50) {
                clearInterval(id);
                console_log('load_script: giving up');
                failure();
                return;
            }
            console_log('load_script: waiting');
        }, 100);
        console_log('load_script: requested');
    }

    function call_function(f) {
        return typeof f == 'function' ? f() : null;
    }

    function console_log(msg) {
        if (debug) console.log(msg);
    }
})();

The require_* functions could be made available from a central repository, so that you can find, copy and paste what you need. But going a bit forward, one could also make orderly support URIs like ‘ord://symbol:module/version’ or ‘ord://symbol:host/module/version’ like ‘ord://j:jquery/1.8.3’ or ‘ord://j:jquery/modal/1.4.2’. They could be used like this:

orderly(
        'ord://j:jquery/1.8.3',
        'ord://j:jquery/modal/1.4.2',
        function() {
            payload(window.j);
        }
    );

and because they are strings, they would not interfere with objects and functions. Execution will then be in two steps: first, request the definition object from the repository and, finally, request the script as specified by the definition object. This will be very similar to what Bundler does for Ruby.