5

I use Module Pattern in my Javascript application, and I want to migrate to RequireJS and AMD.

My current implementation is like this :

// Module main : Module.js
var myModule = (function(my, $, undefined) {
    'use strict';

    var m_privateMembers;
    var m_stuff = new my.Pear({color:"green"});

    //---------------------------------------

    function privateFunctions(args) {
    }

    //-----------------------------------

    my.publicFunctions = function(args) {
    };

    return my;
})(myModule || {}, jQuery);



// Module class Fruit : Module.Fruit.js
var myModule = (function(my, $, undefined) {
    'use strict';

    my.Fruit = Object.makeSubclass();

    my.Fruit.prototype._init = function() {

    };

    my.Fruit.prototype.someClassFunction = function() {
    };

    return my;
})(myModule || {}, jQuery);


// Module class Pear : Module.Pear.js
var myModule = (function(my, $, undefined) {
    'use strict';

    my.Pear = Fruit.makeSubclass();

    my.Pear.prototype._init = function(args) {
        this.m_someClassMember = args;
    };

    my.Pear.prototype.someClassFunction = function() {
    };

    return my;
})(myModule || {}, jQuery);

In my index.html I use script html tags to include my different modules files and everything is working fine.

My question are :

1/ Why RequireJS system is better than this multiple script tags system ?

With my current RequireJS approach :

define(['jquery'], function($) {

    var myModule = (function(my, $, undefined) {
        'use strict';

        var m_privateMembers;
        var m_stuff = new my.Pear({color:"green"});

        //---------------------------------------

        function privateFunctions(args) {
        }

        //-----------------------------------

        my.publicFunctions = function(args) {
        };

        return my;
    })(myModule || {}, $);

    return myModule;
});

2/ How could I migrate to RequireJS modules and keep the singleton-like pattern that my actual modules provide with embedded sub classes ?

obviously there is several problems :

2.1/ *m_stuff can not instantiate my.Pear, and I don't know how to split modules in several files with require ?*

2.2/ If I have two other modules that both are dependent on myModule, will the myModule var be the same instance in those module (since myModule is not in the global scope anymore) ?

edit: this quick schema illustrate what I need to do, in a much more complex framework :

schema

1 Answer 1

2

Why RequireJS system is better than this multiple script tags system ?

I won't go into the in's and outs of this, but just from looking at your existing module setup you can see that AMD would negate the need for explicit script ordering and assigning things to namespaces. The RequireJS build tool would also take care of preparing your scripts for production too.

You can read more

How could I migrate to RequireJS modules and keep the singleton-like pattern that my actual modules provide with embedded sub classes?

Let's look at this by taking Fruit and Pear as examples

When using require or define you are already creating a closure that will encapsulate all your logic, so there is no need to create another one inside. Keep it simple.

// Fruit.js
define(['jquery'], function($) {
    'use strict';

    var Fruit = Object.makeSubclass();

    Fruit.prototype._init = function() {

    };

    Fruit.prototype.someClassFunction = function() {

    };

    return Fruit;
});

// Pear.js
define(['jquery', 'path/to/Fruit'], function($, Fruit) {
    'use strict';

    var Pear = Fruit.makeSubclass();

    Pear.prototype._init = function(args) {
        this.m_someClassMember = args;
    };

    Pear.prototype.someClassFunction = function() {

    };

    return Pear;
});

I don't know how to split modules in several files with require?

Essentially just break up your 'classes' or modules into separate AMD modules and explicitly define the dependencies where needed. You can see from the example above how Pear would use the Fruit module.

If I have two other modules that both are dependent on myModule, will the myModule var be the same instance in those module (since myModule is not in the global scope anymore)?

Once you have required a module once and it is loaded then any other references to it from other modules will get that same instance. For this reason it is often best practice to let your module return a constructor and allow other modules to instantiate it where necessary.

Sign up to request clarification or add additional context in comments.

4 Comments

It is more clear in my mind now, the last thing I don't really understand yet is if I correctly used the same returned var in my modules to wrap them in a common namespace, but it seams to work fine.
There is no need to use a namespace with AMD. The idea is to keep everything contained in modules that don't refer to the global scope
If I work on a framework with several big apps, I tend to split in collections or libraries of modules. I cannot have hundreds of modules on a same flat logical hierarchy (or should I ?). A collection of modules will handle Fruit logic, another will handle totally different tasks like messaging outside the app, etc. I also need to re-use part of the modules in other apps, like for example the messaging library. In fact what I need is more like a C++ namespace, with a Singleton Plugin in each of my lib, and of course all my lib's modules used by my lib plugin and/or other libs modules.
You can (and should) group your modules in a directory structure. This will allow the same organisation as namespaces

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.