5
votes

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

1 Answers

2
votes

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.