1

We have a website that uses several 3rd party javascript libraries, and where possible we'd like to serve them from CDNs to reduce the number of requests on our server. Recently, one of our clients reported a problem using our site, and as it turns out it was because they were blocking one of the CDNs we use (ajax.aspnetcdn.com!). We had been thinking out implementing a failover for the CDNs for sometime but have never gotten around to doing it, and now my manager is pushing us to solve it ASAP.

As is often the case, Scott Hanselman's blog seemed to offer some potential answers, suggesting tools like yepnope and RequireJS. Yepnope has been deprecated, so we chose RequireJS.

We have implemented RequireJS on our site (not a huge job), only to find out it doesn't quite work correctly in IE (absolutely perfect in all other major browsers).

Following the documentation (and some advice from other posts on here), we have set it up as follows. We have this script tag in our html head tag:

<script data-main="/Scripts/main.js" src="/Scripts/require.js" type="text/javascript"></script>

Then in main.js we have configured RequireJS

requirejs.config({
    enforceDefine: true,
    paths: {
        jquery: [
            "https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min",
            "jquery"
        ],
        jqueryui: [
            "https://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min",
            "jqueryui"
        ],
        jqueryunobtrusiveajax: [
            "https://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.unobtrusive-ajax.min",
            "jqueryunobtrusiveajax"
        ],
        jqueryvalidate: [
            "https://ajax.aspnetcdn.com/ajax/jquery.validate/1.7/jquery.validate.min",
            "jqueryvalidate"
        ],
        jqueryvalidateunobtrusive: [
            "https://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.validate.unobtrusive.min",
            "jqueryvalidateunobtrusive"
        ],
        site: [
            "site"
        ],
        localisation: [
            "localisation"
        ]
    },
    shim: {
        jqueryui: {
            deps: ['jquery'],
            exports: "$"
        },
        jqueryvalidate: {
            deps: ['jquery'],
            exports: '$'
        },
        jqueryvalidateunobtrusive: {
            deps: ['jquery', 'jqueryvalidate'],
            exports: '$'
        },
        jqueryunobtrusiveajax: {
            deps: ['jquery'],
            exports: '$'
        },
        localisation: {
            deps: ['jquery', 'jqueryui', 'jqueryvalidate'],
            exports: '$'
        },
        site: {
            deps: ['jquery', 'jqueryui', 'jqueryvalidate', 'jqueryvalidateunobtrusive'],
            exports: '$'
        }
    }
});

Note that as per the advice on how to "Catch load failures in IE" on RequireJS's GitHub Wiki we have set enforceDefine to true, and used define() to define a module (we want the same scripts on every page) before using require(), like this:

define('main', ["jqueryui", 'jqueryvalidate', 'jqueryvalidateunobtrusive', 'jqueryunobtrusiveajax', 'localisation', 'site'], function () { 
    // we have some code here that confirms each script is loaded, looks a bit like this (one for each script):
    if (jQuery) {
        console.log("jQuery");
    } else {
        console.error("jQuery");
    }
});

Then on each page we simply add the following script tag:

<script type="text/javascript">
    require(["main"], function() {
        // any page specific script goes here
    });
</script>

This works just fine in all browsers (including IE), BUT it does not work in IE if you block any of the CDNs. Oddly it works just fine if you change the url for CDN files to something that doesn't exist, or remove the CDN url entirely (so just serve the local file). If I block the CDN by adding the domain to internet options -> security -> restricted sites in IE, it takes ages (5-10 secs) attempting to load the scripts, then times out on the two local only files (site.js and localisation.js):

SCRIPT5022: Load timeout for modules: localisation,site http://requirejs.org/docs/errors.html#timeout

All the other browsers cope just fine if I block the CDNs (using AdBlock Plus), does anyone know why I am experiencing this behaviour with IE?

Ben
  • 5,525
  • 8
  • 42
  • 66
  • Yepnope has been deprecated? Says who? – Blazemonger Mar 30 '15 at 14:24
  • 1
    There is [a simpler cross-browser approach](http://stackoverflow.com/questions/1014203/best-way-to-use-googles-hosted-jquery-but-fall-back-to-my-hosted-library-on-go) to providing a local fallback for CDNs, which you should be doing anyway. – Blazemonger Mar 30 '15 at 14:26
  • lol @Blazemonger says yepnopejs.com! I thought about that approach, but not all of the libraries have a property or object that you can test to see if they are loaded (jqueryunobtrusiveajax for example). That said, I am now looking into that approach thanks – Ben Mar 30 '15 at 14:35

0 Answers0