9
\$\begingroup\$

I am in between to create JavaScript Boilerplate (collection of best practices around) for low/medium complex project and will host on GitHub in sometime once finalized it.

Have divided the JavaScript modules in 3 parts

  1. project.config.js - Would have all the required configuration
  2. project.main.js - the JS Boilerplate
  3. project.helper.js - would have most commonly used functions, user may or may not want it

project.config.js

/* MODULE (our namespace name) and undefined are passed here 
 * to ensure 1. namespace can be modified locally and isn't 
 * overwritten outside of our function context
 * 2. the value of undefined is guaranteed as being truly 
 * undefined. This is to avoid issues with undefined being 
 * mutable pre-ES5.
*/
(function (MODULE, undefined) {
    MODULE.config = {
        language: 'english',
        debug: true,
        etc...
    }
}(window.MODULE = window.MODULE || {}))

project.main.js:

/* MODULE (our namespace name) and undefined are passed here 
 * to ensure 1. namespace can be modified locally and isn't 
 * overwritten outside of our function context
 * 2. the value of undefined is guaranteed as being truly 
 * undefined. This is to avoid issues with undefined being 
 * mutable pre-ES5.
*/

(function( MODULE, $, undefined ){
/**
 * Logging function, for debugging mode
 */
jQuery.log = function(message) {
    if( (typeof window.console != 'undefined' && typeof window.console.log != 'undefined') && console.debug ) {
        console.debug(message);
    } else {
        //alert(message);
    }
};

/**
 * Private properties
 */
var foo = "foo", 
    bar = "bar";

/**
 * Public methods and properties
 */
MODULE.foobar = "foobar";
MODULE.sayHello = function () {
    speak("hello world");
};

/**
 * Private method
 */

/* Benefits:
 * 1. Makes it easier to understand "functions as an object".
 * 2. It enforces good semicolon habits.
 * 3. Doesn't have much of the baggage traditionally associated with functions and scope.
 */
var getData = function () {
};

/* Singleton with Privileged Methods */
MODULE.subModule = (function () {
    function _subModule() {
        /**
         * Init call
         */
        var _this = this;   /* Store this to avoid scope conflicts */

        /**
         * facebookLogin - FB.login prompts the user to authorize your application
         */
        this.facebookLogin = function () {
        }

        /**
         * private method
         */
        var privateMethod = function() {
        };

        this.init = function () {
            _this.facebookLogin();
            return this;
        };

        return this.init();
    }

    return new _subModule();
}());
})(window.MODULE = window.MODULE || {}, jQuery)

Though it's pretty straight forward with comments and all but anyway let me elaborate it further, have been using Global Abatement using namespace, singleton inside the SIAF (to protect the scope and follow encapsulation) and using privileged private methods inside it and executing the privileged one in init().

And essentially returning the submodule in the last to available to the window level using namespace (MODULE).

Looks pretty neat but still looking to make it better and robust.

Would appreciate code review comments here.

Thanks for your time.

\$\endgroup\$
2
  • \$\begingroup\$ BTW JavaScript Boilerplate has been on Git now @ github.com/mdarif/JavaScript-Boilerplate where I have integrated the review comments. And again anyone of you, have anything to add or have good suggestion, do send out the 'Pull' request which I can review and implement if feasible. \$\endgroup\$ Jun 6, 2012 at 6:28
  • \$\begingroup\$ It's also available as npm package, run $ npm install javascript-boilerplate \$\endgroup\$ May 14, 2013 at 11:10

1 Answer 1

1
\$\begingroup\$

Interesting work Arif. I really loved to see different as well as interesting JS patterns you have used. It is looking to me like, it is going in a good and right direction.

Few things that you might consider to do is

I) Create some example of different modules and ensure they are in different files (it is not very clear with the current example but I assume you have already thought about it).

II) Might be a very personal choice, I don’t like _ in variable and method names. The way I know what is public and what is private is by looking at what is being returned at the bottom, as I use a pattern like below in most occasions

    (function(MODULE, $)  {
       MODULE.charting = function(options) {
          options = $.extend({
              defaultParam1: “a”,
              defaultParam2: “b”
          }, options);

          var xAxis, yAxis;

          function render() {

          }

          function destroy() {

          } 

          (function init() {
             //Anything that is suppose to be called when a object of the
             //module is created. Acts like a psuedo constructor.
          })();

          return {
             render: render,
             destroy: destroy
          };
       };
     }(MODULE || {}, jQuery));

What do you think? In above example you can clearly see what is public and they can be exposed with a different name if one wants. So in refactoring it will not break other components as the way it is exposed outside can be different. If you see what I mean.

III) If you are using jQuery, you can use extend like above to define defaults and then override if passed by the user.

IV) Generally I don’t tend to put URLs in JavaScript and prefer to put them on jsp, asp, json response, etc. as then front-end doesn’t need to worry about context/domain/port.

Will send you more comments if I think of any. For the time being have a think about it and let me know your views. Also keep on sharing the progress, would love to see this growing into a very fruitful thing.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for the comments Manish. You are right for #1 would be creating different modules in separate file. #2, you talking about "Revealing Module Pattern" which has few issues like a private function refers to a public function, that public function can't be overridden if a patch if necessary. This is because the private function will continue to refer to the private implementation and the pattern doesn't apply to public members, only to functions. I just tried to kept it simple and hence using Privileged Methods most of the time & exposing in init(). \$\endgroup\$ May 31, 2012 at 4:12

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.