4
\$\begingroup\$

I've written a small webapp in JavaScript, and am now essentially rewriting it to use RequireJS. I'm doing this partly to get more familiar with RequireJS (which I have little experience with), as well as for ease of maintaining and upgrading the app.

I'm hoping to get feedback on whether the structure I'm looking at implementing is reasonable/useful/extensible/totally insane. I've been through the require docs, reading related SO posts and some samples on GitHub, but I'm not sure I'm totally 'getting' Require.

If there are fundamental flaws in the logic it'd be great to get some links to resources (either JS or RequireJS specific), and to get feedback about the overall structure of the app itself. Suggestions for design patterns also very much appreciated, there's some stuff in there that feels kind of counter intuitive.

main.js

require({

    paths: {
        jquery: '../bower_components/jquery/jquery'
    }

}, function() {
    'use strict';
    require(['jquery', 'app', 'reader', 'env'], function($, App, Reader, Env) {

        $(document).ready(function() {

            var app = new App(
                new Reader(),
                new Env()
            );

        });

    })

});

app.js

define(function() {

    return function(reader, env) {

        this.reader = reader,
        this.env = env

    };

});

reader.js (it's an online e-reader)

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

    return function() {

        this.components = [],
        this.firstPage = null,
        this.lastPage = null,
        this.maxFontSize = function() {
            return this.env.isIOS() ? 120 : 160;
        }

    };

});

env.js

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

    return function() {

        this.isIOS = function() {
            return navigator.userAgent.match(/(iPad|iPhone|iPod)/i) ? true : false; // for example.  
        }

    };

});
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

This is honestly pretty good. I usually use requirejs.config to set the paths and configurations on require (it's going to grow a lot as you add things like shims, urlArgs, etc). You will also probably want to reuse it in several places. See my blog article on how I recommend doing this. The general idea is that you don't use data-main to bootstrap things, you instead have a request for the configuration file and another to actually bootstrap the specific page of your application.

Next, I'll ask why bother injecting reader and env manually into application? Injecting dependencies is what RequireJs already does.

app.js

define(['reader', 'env'], function(Reader, Env) {
    return function() {
        this.reader = new Reader(),
        this.env = new Env()
    };
});

Finally, a couple notes on your specific files - you probably want to name those top-level functions even when returning immediately

env.js

define(['jquery'], function($) {
    return function Env() {
      ...
    };
});

That both makes it clear from within what module you're in, the fact that you expect it to be used with new, and will generate nicer stacktraces.

I'll also point out that - it's a matter of style but you're on CR so I consider it solicited - hardly ever is code made more bugproof or more legible by using constructor functions. reader.js could just as easily be the following and not depend on someone remembering to use new and always bind functions.

var env = {
    components: [],
    firstPage: null,
    lastPage: null,
    maxFontSize: function() {
                   return this.env.isIOS() ? 120 : 160;
                 }
};
return env;
\$\endgroup\$
1
  • \$\begingroup\$ hey thanks very much! injecting the deps manually was part of what was feeling strange about what i had going on in the Q. i set up the require.config, named the top level fns (the console.log looks logical now) and removed constructors (reader.js) where superfluous. thanks also for the link! \$\endgroup\$
    – mzmm56
    Mar 26, 2014 at 9:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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