RequireJS: local fallback for if CDN fails

W mojej aplikacji szkieletowej, muszę zapewnić awaryjne dla każdego wymaganego pliku, w przypadku, gdy CDN, który je dostarcza, zawiedzie.

Próbowałem nadpisać require.onError Tak:

require.onError = function (err) {
    if (err.requireType === 'timeout') {
        var url = err.requireModules;

        if (!!~url.indexOf("jquery/"))
            console.warn("CDN timed out, falling back to local jQuery.js")
            require(["libs/jquery"]);
            return;
        if (!!~url.indexOf("jqueryui/"))
            console.warn("CDN timed out, falling back to local jQueryUI.js")
            require(["libs/jqueryui"]);
            return;
        if (!!~url.indexOf("underscore"))
            console.warn("CDN timed out, falling back to local underscore.js")
            require(["libs/underscore"]);
            return;
        if (!!~url.indexOf("backbone"))
            console.warn("CDN timed out, falling back to local backbone.js")
            require(["libs/backbone"]);
            return;
    }
}

Problem polega na tym, że spowoduje to asynchronicznie załadowanie plików zapasowych. Potrzebuję tych plików, aby załadować je w kolejności, tak jak oryginalna instrukcja require, gdzie używam wtyczki order!.

Z nadpisanym onError: gdy CDN nie ładuje się, uruchamiane jest awaryjne ładowanie, ale nie czekano na nie. Stanowi to problem, ponieważ skrypty są ładowane zgodnie z ich zależnościami. Oto spojrzenie na moje oryginalne require stwierdzenie, które zależy od CDN:

require([
    "order!http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js",
    "order!http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js",
    "order!http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.3/underscore-min.js",
    "order!http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js",
    "order!utils/date",
    "order!core/core",
    "order!core/errors",
    "order!core/constants"
], function() {
    ...
}
Author: Austin, 2012-08-22

2 answers

Jakiej wersji RequireJS używasz? Wydaje się, że powinieneś skonfigurować jQuery jako ścieżkę w konfiguracji, a następnie skonfigurować jQuery jako zależność od innych modułów, które tego potrzebują. Jeśli używasz ~ > 2.0, coś w stylu (untested):

// in your requirejs config
requirejs.config({
    //To get timely, correct error triggers in IE, force a define/shim exports 
    // check.
    enforceDefine: true,
    paths: {
        jquery: [
            'http://somecdn.com/jquery.min', // your cdn
            'lib/jquery' // your fallback
        ],
        jqueryui: "http://somecdn.com/jquery-ui.min.js"
    },
    shim: {
      jqueryui: ['jquery']
    }
});

// then in your requires
require([jquery, jqueryui, foo, bar], function($) {
    // stuff
});

Mówią o tym, jak to zrobić w wiki . Jeśli nie używasz v2.x, tutaj też jest metoda na radzenie sobie z tym.

Jeśli wszystkie moduły są skonfigurowane tak, aby określały własne zależności, nie musisz bądź też zaniepokojony dyrektywami order!.

 57
Author: numbers1311407,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-22 14:25:09

Znalazłem rozwiązanie problemu podanego w RequireJS 2.x. X. było zapotrzebowanie na to rozwiązanie, więc z kolei RequireJS dodał obiekt paths do ich konfiguracji. Zapewnia to funkcję awaryjną dla CDN, w przypadku ich niepowodzenia.

Należy również zauważyć, że wtyczka order! została przestarzała w Require 2.0, więc musiałem również użyć obiektu shim do zdefiniowania zależności. To całkiem ciekawy pomysł.

Oto mój nowy wymagają.config:

require.config({
    urlArgs: "ts="+new Date().getTime(), // disable caching - remove in production
    paths: {
        jquery: [
            "http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min",
            "libs/jquery"
        ],
        jqueryui: [
            "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min",
            "libs/jqueryui"
        ],
        underscore: [
            "http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.3/underscore-min",
            "libs/underscore"
        ],
        backbone: [
            "http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min",
            "libs/backbone"
        ]
    },
    shim: {
        'jqueryui': ['jquery'],
        'underscore': ['jquery'],
        'backbone': ['underscore'],
        'core/core': ['underscore'],
        'core/errors': ['core/core'],
        'core/constants': ['core/core']
    }
});
 19
Author: Austin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-22 14:25:41