Подтвердить что ты не робот

RequireJS: локальный резерв, если CDN не работает

В моем базовом приложении мне нужно предоставить резерв для каждого требуемого файла в случае, если CDN, который их поставляет, терпит неудачу.

Я попытался перезаписать require.onError следующим образом:

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

Проблема заключается в том, что это будет асинхронно загружать резервные файлы. Мне нужно, чтобы эти файлы загружались по порядку, так же как и исходный запрос require, где я использую плагин order!.

С переопределенным onError: когда CDN не загружается, резервная загрузка запускается, но не дожидается. Это создает проблему, потому что сценарии упорядочены для загрузки на основе их зависимостей. Вот посмотрите на мою оригинальную инструкцию require, которая зависит от 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() {
    ...
}
4b9b3361

Ответ 1

Какую версию RequireJS вы используете? Кажется, вы захотите настроить jQuery fallback как путь в вашем конфиге, а затем настроить jQuery как зависимость от других модулей, которые в ней нуждаются. Если вы используете ~ > 2.0, что-то вроде (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
});

Они говорят о том, как это сделать в вики. Если вы не используете v2.x, есть метод для обработки и здесь.

Если все модули сконфигурированы для указания своих собственных зависимостей, вам не нужно беспокоиться о директивах order!.

Ответ 2

Я нашел решение проблемы, заданной в RequireJS 2.x.x. Был спрос на это решение, поэтому, в свою очередь, RequireJS добавил объект paths в свою конфигурацию. Это обеспечивает резервную функциональность для CDN, если они не сработают.

Следует также отметить, что плагин order! устарел в Требовании 2.0, поэтому мне также нужно использовать объект shim для определения зависимостей. Это действительно довольно интересная идея.

Вот мой новый require.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']
    }
});