简体   繁体   中英

requireJS module loading

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?

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()
            })
        });
    }
})

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM