3

I need some help with the concept of only loading modules when they are needed using requireJS

this is my main.js

require(['jquery', 'path/somemodule'],
function($, somemodule) {
$(document).ready(function() {
    somemodule.init()
})

})

and in the somemodule.js

 define(['jquery', 'path/someothermodule'], function ($, someothermodule) {
 "use strict";
var somemodule;

somemodule = {
init: function () {
    someothermodule.init()
}
}
return somemodule;
)}

right now somemodule.js and someothermodule.js is loaded on all pages. How do I only load it when it's needed?

2
  • it's loading on all pages because... it's needed on all pages currently. main.js requires path/somemodule, and somemodule.js requires path/someothermodule. Therefore, any time you include main.js, it's going to also include somemodule.js and someothermodule.js. Commented Oct 17, 2013 at 20:32
  • You fire require only when you need the module, so it doesn't need to be on all pages unless you load it there. Commented Oct 17, 2013 at 20:37

2 Answers 2

7

When you require a module2 from module1 using the standard define() syntax module1 will not load/run until module2 has been fully loaded. That looks like this:

// inside module1
define(['module2'], function(mod2) {
   // we don't get here until AFTER module2 has already been loaded
});

An alternative to lazy-load module2 looks like this:

// inside module1
define([], function() {
   require(['module2'], function(mod2) {
       // we don't get here until AFTER module2 has already been loaded
   });
   // but we DO get here without having loaded module2
});

Now you have to program somewhat carefully to make sure you don't run into any issues with asynchronicity.

In your case you can modify your main.js file

require(['jquery'],
function($) {
    // jquery is loaded, but somemodule has not

    if(thisPageNeedsSomeModule) {
        require(['path/somemodule'],
        function(somemodule) {
            // now somemodule has loaded
            $(document).ready(function() {
                somemodule.init()
            })
        });
    }
})
Sign up to request clarification or add additional context in comments.

1 Comment

I get it now. You helped me a lot
0

Your main.js file will load any file paths provided to it, so long as other elements of your application specify them as dependencies. See my example main.js file:

require.config({

    paths: {
        'app': 'app',
        'underscore':'bower_components/underscore/underscore-min',
        'backbone':'bower_components/backbone/backbone-min',
        'marionette':'bower_components/backbone.marionette/lib/backbone.marionette.min',
        'jquery': 'bower_components/jquery/jquery.min',
        'tpl':'bower_components/requirejs-tpl/tpl',
        'bootstrap':'bower_components/bootstrap/dist/js/bootstrap.min',
        'leaflet':'bower_components/leaflet/leaflet',
        'leaflet.markercluster':'bower_components/leaflet/leaflet.markercluster',
    },
    shim: {
        'underscore': {
            exports: '_'
        }, 
        'leaflet': {
            exports: 'L'
        }, 
        'leaflet.markercluster': {
            deps: ['leaflet']
        },
        'backbone': {
            deps: ['underscore']
        },
        'marionette': {
            deps: ['backbone']
        },
        'jquery': {
            exports: '$'
        },  
        'bootstrap': {
            deps: ['jquery']
        },
        'app': {
            deps: ['jquery', 'leaflet','bootstrap', 'leaflet.markercluster', 'marionette', 'tpl']
        },
        'app.elem': {
            deps:['app']
        },
        'app.api': {
            deps:['app']
        }
    }
})

require(['app','app.api','app.elem'], function() {
    App.start();
})

And my initial application file:

define(['router', 'collections/moments'], function(router, momentCollection) {

    // Boot the app!

    App = new Marionette.Application();

    App.LocResolve = false; // Have we resolved the user's location?
    App.Locating = true; // Are we actively tracking the user's location?

    App.FileReader = window.FileReader ? new FileReader : null;

    App.Position = null; // Instant access to Lat & Lng of user.

    App.MomentsRaw = null; // Keep cached copy of returned data for comparison.

    App.Moments = new momentCollection; // Current collection of moments.
    App.Markers = new L.MarkerClusterGroup(); // Create Marker Cluster Group

    App.View = null; // Current view.

    // Marionette Regions

    App.addRegions({
        header: '#header',
        map: '#map',
        list: '#list',
        modal: '#modal',
    });

    return App
})

I noticed that you aren't passing in a configuration object - is this intentional? If you use R.js, the build optimizer, it will automatically remove unused vendor files for you.

In short, sets paths to your vendor files in the require.js config, then call upon them via define() whenever you need a particular asset. This will ensure that only files you need are used. Hope this helps!

1 Comment

Can you please explain to me. If I only want to load somemodule.js with somemodule.init() when a specific element is present. It will help me better understand

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.