Как сделать плагин jQuery загружаемым с помощью requirejs


88

Я работаю с requirejs + jquery, и мне было интересно, есть ли разумный способ заставить плагин jQuery хорошо работать с require.

Например, я использую jQuery-cookie. Если я правильно понял, я могу создать файл с именем jquery-cookie.js и внутри сделать

define(["jquery"], // Require jquery
       function($){
// Put here the plugin code. 
// No need to return anything as we are augmenting the jQuery object
});
requirejs.config( {
    "shim": {
        "jquery-cookie"  : ["jquery"]
    }
} );

Мне было интересно, могу ли я делать такие вещи, как jQuery, а это примерно так:

if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
    define( "jquery", [], function () { return jQuery; } );
}

или если это единственный способ сделать плагины jQuery совместимыми с requirejs или любыми amd

Ответы:


67

Вам нужно только сделать ЛИБО

define(["jquery"], // Require jquery
       function($){
// Put here the plugin code. 
// No need to return anything as we are augmenting the jQuery object
});

в конце jquery-cookie.js ИЛИ

requirejs.config( {
    "shim": {
        "jquery-cookie"  : ["jquery"]
    }
} );

в любом месте, прежде чем вы включите jquery-cookie (например, туда, куда указывает основные данные).

Последний опубликованный вами блок кода хорош для таких вещей, как jQuery, которые распространяются и могут находиться или не находиться в среде AMD. В идеале каждый плагин jQuery уже должен иметь такую ​​настройку.

Я предпочитаю сохранять включенные библиотеки как можно более чистыми , поэтому глобальная конфигурация прокладки один раз на страницу кажется мне самым чистым решением . Таким образом, обновления будут более безопасными, а сети CDN станут возможными.


1
Если я не выполняю и определение, и прокладку, все не работает, я получаю сообщение об ошибке $ .cookie не является функцией,
— Никола Пелучетти,

По моему опыту, недостаточно ничего не вернуть из определяющей функции, requirejs не распознает, что модуль загружен. Это можно разбудить с помощью shim: {plugins: {sizes: ['jquery'], exports: 'plugins'}
— honzajde

Обратите внимание, что скрипт плагина jQuery действительно должен запускаться. Я не эксперт, но я нашел простое решение, при котором у вас есть один require(['plugin1', 'plugin2']);и т. Д. Обратный вызов не передается, поэтому ничего не будет выполняться, кроме самих сценариев плагина. Это означает, что затем они будут добавлены, jQuery.fnпоэтому везде, где вы можете просто указать jquery в качестве зависимости, они будут включены. Как я уже сказал, я новичок в этом, и может быть лучший подход (например, просто использование scriptтега), но это действительно работает.
— Джошуа Бамбрик

3
Джош: Вы делаете ставку на то, что все загрузится в правильном порядке. Некоторые пользователи на вашем сайте, вероятно, видят неисправный материал. Проблема не столько в том, что плагин загружается, а в том, когда плагин загружается и что еще выполняется в это время. Основная причина использования require - обеспечить разумный порядок операций, основанный на зависимостях, а не на предположениях.
— Hans

104

Есть некоторые предостережения при использовании конфигурации прокладки в RequireJS, указанные на http://requirejs.org/docs/api.html#config-shim. . А именно: «Не смешивайте загрузку CDN с конфигурацией прокладки в сборке», когда вы используете оптимизатор.

Я искал способ использовать один и тот же код плагина jQuery на сайтах как с RequireJS, так и без него. Я нашел этот фрагмент для плагинов jQuery по адресу https://github.com/umdjs/umd/blob/master/jqueryPlugin.js . Вы оборачиваете свой плагин этим кодом, и он в любом случае будет работать правильно.

(function (factory) {
if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module depending on jQuery.
    define(['jquery'], factory);
} else {
    // No AMD. Register plugin with global jQuery object.
    factory(jQuery);
}
}(function ($) {

    $.fn.yourjQueryPlugin = function () {
        // Put your plugin code here
    };  

}));

Кредит идет на jrburke; как и многие другие javascript, он функционирует внутри функций, воздействуя на другие функции. Но я думаю, что распаковал то, что он делает.

Аргумент функции factoryв первой строке сам по себе является функцией, которая вызывается для определения плагина для $аргумента. Когда AMD-совместимый загрузчик отсутствует, он вызывается непосредственно для определения подключаемого модуля в глобальном jQueryобъекте. Это похоже на распространенную идиому определения плагинов:

function($)
{
  $.fn.yourjQueryPlugin = function() {
    // Plugin code here
  };
}(jQuery);

Если есть загрузчик модуля, то factoryон регистрируется как обратный вызов для загрузчика, вызываемого после загрузки jQuery. Загруженная копия jQuery является аргументом. Это эквивалентно

define(['jquery'], function($) {
  $.fn.yourjQueryPlugin = function() {
     // Plugin code here
  };
})

3
Мне нравится этот ответ, потому что, хотя вопрос был о плагине jQuery, он работает для любого модуля или библиотеки, а не только для jQuery. Мне потребовалась минута, чтобы осмыслить ваш код, но как только я это сделал, это стало совершенно логичным.
— Адам Таттл

1
Это определенно непонятный javascript. Я добавил несколько пояснений о том, как это работает.
— Карл Рэймонд

Есть какие-нибудь советы, как это сделать и создать плагин, работающий с jQuery или Zepto? Вы можете легко заменить код, не относящийся к AMD, наfactory(jQuery || Zepto); , , но я не знаю, как бы вы сделали часть AMD. Я думаю, вам нужно установить jQuery "путь" к zepto ?? paths: { jquery: 'vendor/zepto/zepto.min' }
— Райан Уил

вау, я давно хотел понять этот фрагмент кода. Большое спасибо, разве shimэто не так? Думаю, нет ... потому что вы сказали, что вручную кодируете, как указано выше.
— Евгений

Совет для идиотов вроде меня: где написано $.fn.jqueryPlugin измените jqueryPluginназвание плагина во фрагменте !!
— Мэтт Лейси

2

Так же, как к сведению, некоторые плагины jquery уже используют amd / require, поэтому вам не нужно ничего объявлять в прокладке. На самом деле в некоторых случаях это может вызвать у вас проблемы.

Если вы посмотрите в jquery cookie JS, вы увидите определение вызовов и require (["jquery"]).

и в jquery.js вы увидите вызов для определения ("jquery", [], function () ...

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.