irysius
irysius

Reputation: 600

Is there a way to conditional load a module via RequireJS based on whether or not the module 404s?

Problem: We currently have the following require.config:

require.config({
    paths: {
        lodash: '/embed/lodash',
        utils: '/embed/utils',
        analytics: '/external/analytics'
    }
});

file paths that start with embed are guaranteed to exist. file paths that start with external may or may not be available, depending on the environment. If I begin my main.js with the following:

require(['lodash', 'utils', 'analytics'], function (_, utils, analytics) {

and analytics can't be found, the whole thing crashes (as expected). Trying variations on the following proved fruitless:

require(['lodash', 'utils'], function (_, utils) {
    ...code and stuff
    $.ajax({ url: '/path/to/actual/file' })
        .done(function () {
            require(['analytics'], function (analytics) {
                // throws Mismatched anonymous define() module Error
            });
        })
        .fail(function () {
            // continue with stub of analytics
            // or not run analytics dependent code
        });

As per the title of this question: Is there a way to conditionally include a module in RequireJS based on whether or not the file is accessible?

Upvotes: 2

Views: 4310

Answers (2)

irysius
irysius

Reputation: 600

From my colleague, who provided the correct solution to my problem, and kindly told me to RTFM: http://requirejs.org/docs/api.html#errbacks

Keeping "normal" declaration of require.config, just add an error callback to handle the case when the module can't be found.

require(['lodash', 'utils'], function (_, utils) {
    ...code and stuff
    require(['analytics'], function (analytics) {
        // normal execution

    }, function (error) {
        // continue with stub of analytics
        // or not run analytics dependent code at all

    });

Upvotes: 3

Vishwanath
Vishwanath

Reputation: 6004

If you want fallback to be downloaded when your external file is not available, you can use path fallback configuration in requireJS.

Set your path configuration like following.

require.config({
    paths: {
        lodash: '/embed/lodash',
        utils: '/embed/utils',
        analytics: ['/external/analytics',
                     '/embed/analytics'
                ]
    }
});

Then create a file analytics.js in embed directory which gives you the object normally returned by analytics from outside. If external/analytics adds a object in the global namespace, do that as well.

embed/analytics.js

define(function(){
    var analytics = window.analytics = {
        send : function(){
            //Nothing to do here.
        }
        //,... //Add more methods used by your code like send
    }
    return analytics;
});

Upvotes: 3

Related Questions