Правильный способ реализации jQuery с require.js

Я использую текущую стабильную версию как require.js, так и jQuery, и в настоящее время я использую jQuery, подобный этому

requirejs.config({
paths: {
    'jQuery': 'vendor/jquery',
}
});

require(['jQuery'], function(jQuery) {
    log(jQuery); // working
});

Я не понимаю, что мне явно не нужно явно возвращать jQuery, поскольку это все равно будет работать (также в других модулях):

require(['jQuery'], function( // nothing here ) {
    log(jQuery); // working
});

Теперь я не уверен, что это правильный способ сделать это, потому что использование знака $доллара для ссылки на jQuery не работает!

Ответ 1

Ключевые моменты, которые я вижу:

  • jQuery, когда используется с RequireJS, регистрируется как именованный модуль jquery (все строчные буквы). В вашем примере вы пытаетесь использовать его как "jQuery", что немного путает вещи, поскольку это также имя глобальной функции, которую он регистрирует при загрузке (см. Пункт 2).
  • По умолчанию jQuery регистрирует себя, используя глобальные функции "$" и "jQuery" даже при использовании с AMD/RequireJS. Если вы хотите отключить это поведение, вам нужно вызвать функцию noConflict.
  • Вы можете привязать вашу ссылку RequireJS к jQuery в вызове noConflict, как показано в примере ниже. Насколько я могу судить, это рекомендуемый подход, когда у вас нет других модулей, которым нужен глобальный $или jQuery:

    requirejs.config({
        paths: {
            'jquery': 'vendor/jquery',
        }
    });
    
    define('jquery-private', ['jquery'], function (jq) {
        return jq.noConflict( true );
    });
    
    require(['jquery-private'], function(jq) {
        console.log(jq);      // working
        console.log($);       // undefined
        console.log(jQuery);  // undefined
    });
    

См. также мой ответ в этом вопросе о том, как сопоставить другие модули для использования частной (noConflict) версии.

Для получения дополнительной информации см. эти строки из исходного кода jQuery, которые являются причиной всего, что я описал выше:

    // Expose jQuery to the global object
    window.jQuery = window.$ = jQuery;

    // Expose jQuery as an AMD module, but only for AMD loaders that
    // understand the issues with loading multiple versions of jQuery
    // in a page that all might call define(). The loader will indicate
    // they have special allowances for multiple jQuery versions by
    // specifying define.amd.jQuery = true. Register as a named module,
    // since jQuery can be concatenated with other files that may use define,
    // but not use a proper concatenation script that understands anonymous
    // AMD modules. A named AMD is safest and most robust way to register.
    // Lowercase jquery is used because AMD module names are derived from
    // file names, and jQuery is normally delivered in a lowercase file name.
    // Do this after creating the global so that if an AMD module wants to call
    // noConflict to hide this version of jQuery, it will work.
    if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
        define( "jquery", [], function () { return jQuery; } );
    }

UPDATE: Использование с секцией jQuery сайта RequireJS обновлено, чтобы отразить вышеприведенную информацию. См. Также этот ответ за шаг за шагом, включая оптимизатор. Просто хочу еще раз подчеркнуть, что этот подход noConflict работает только в том случае, если все ваши плагины совместимы с AMD.