Organizing JavaScript code for a website I'm in the process of building a website for the company I work for and I'm trying to think of the best way to namespace and organize the site's JavaScript code.

I've written several jQuery/JavaScript plugins for the big chunks of code, but now I'd like a namespaced place to "call" said plugins and any other random JavaScript that's needed throughout the site.

I'm considering using a singleton (NAMESPACE.js):

// http://stackoverflow.com/a/1479341/922323
var NAMESPACE = (function() {

    //var privateVar = '';

    function weather() {

        var $weather = $('#weather');

        if ($weather.length) {

            // Do jQuery stuff with $weather here.

        }

    } // weather()

    function navigation() {

        var $baz = $('#baz'),
        $html = $('html');

        $baz
            .myOtherPlugin({
                cloneRemove : 'li &gt; div',
                cloneId     : false
            })
            .anotherPlugin({
                eventType      : 'hoverIntent',
                onStartOutside : function() {
                    $html.addClass('mw-outside');
                },
                onEndOutside   : function() {
                    $html.removeClass('mw-outside');
                }
            });

    } // navigation()

    function footer() {

        $('footer ul').myPlugin({
            //openTab : true,
            currentPage : true
        });

    } // footer()

    return {

        init : function() {

            weather();

            navigation();

            footer();

            // Add more here as project grows...

        } // init()

    };

})();


HTML would look like so (in foot of document):

&lt;script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"&gt;&lt;/script&gt;
&lt;script src="plugins.js"&gt;&lt;/script&gt;
&lt;script src="NAMESPACE.js"&gt;&lt;/script&gt;

&lt;script type="text/javascript"&gt;
    &lt;!--

        $(document).ready(function() {

            NAMESPACE.init();

        });

    //--&gt;
&lt;/script&gt;


Question(s):


Do you see anything out of the ordianary with my (pseudo) code above?
Am I headed in the right direction? If not, could you suggest an alternative?
Am I over-complicating things?
I really like how Yahoo! does: YAHOO.namespace("myProject"); YAHOO.myProject.myModule = function () { ... } ... it seems like if I did something similar, that would allow me to easily add/remove "modules" on a "per page" basis. Would anyone recommend this approach? If so, how could I modify my example to mimic YUI's functionality (I'm going to research YUI's namespace() code and post back my results if I figure it out).
One problem in your code is that the "modules" aren't standalone. You'd be adding the "modules" for calling into the init every time a new on is made.

To avoid doing so, each module should register itself for init. You can do this by adding a "register" functionality in your singleton.

(function(exports){

    var registry = []; //collection of module

    //adds module to collection
    exports.register = function(moduleDeclaration){
        registry.push(moduleDeclaration);
    }

    //executes every module
    exports.init = function(){
        var registryLength,i;

        registryLength = registry.length

        //loop through each module and execute
        for(i=0;i&lt;registry.length;i++){
            registry[i].call(this);
        }
    }

//use existing namespace or make a new object of that namespace
}(window.Lib = window.Lib || {}));

//To register a module
Lib.register(function(){
    //do what you have to do here
});

//executing the init
Lib.init();


See? The modules register themselves and don't need to be added manually for init. A developer can create a module on a separate file, add it into the page without editing the main Lib singleton.

Also, you'd have to consider what you'd do if you include a module dynamically after init is called. You should have some internal flag to indicate that init was already called, and that dynamically added module should register and execute immediately.



A vaguely known library called KernelJS already does this and contains many more features like core abstraction, pub-sub inter-module communication, register-remove modules, loose coupling pattern and so on. I suggest you try it or base from it.



As an answer to your add-on question of exposing modules, sure you can. However, according to scalability principles, modules or "widgets" as they call them, should not know each exists. This is to prevent tight-coupling and avoid breakage when, for example, you take out a certain module out. 

Also, naming modules isn't good for portability as you are setting a fixed name for a set of code. What if you changed it's name? You'd have to look for all code that depends on that module and change the name.

However, if you want to have named modules and fetching badly, you could expose another function to retrieve a module and return that module if it exists, or undefined or a custom error if it doesn't. Here's modified code for Lib. Since we are using named modules, instead of an array, registry is now an object.

var registry = {}

exports.register = function(name,declaration){
    registry[name] = declaration;
}

exports.init = function(){
    var module,i;

    registryLength = registry.length

    //loop through each module and execute
    for(name in registry){
        if(registry.hasOwnProperty(name)){
            registry[name].call(this);
        }
    }
}

exports.getModule = function(moduleName){

    //default to undefined
    var module;

    //if module exists, assign
    if(registry.hasOwnProperty('moduleName')){
        module = registry[moduleName];
    }

    return module
}

//to register a module
Lib.register('moduleName',function(){
    //module code
});


Additionally, you can call each module's init from Lib's init. Just make sure each module exposes an init function.