Як зробити плагін jQuery доступним для завантаження за допомогою requirejs


88

Я працюю з requirejs + jquery, і мені було цікаво, чи є розумний спосіб зробити так, щоб плагін jQuery добре працював з require.

Наприклад, я використовую файл cookie jQuery. Якщо я правильно зрозумів, я можу створити файл з назвою 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"]
    }
} );

де завгодно, доки ви не включите файл cookie jquery (наприклад, де б не вказували основні дані, наприклад).

Останній опублікований код коду підходить для таких речей, як jQuery, які перерозподіляються, а можуть і не бути в середовищі AMD. В ідеалі кожен плагін jQuery мав би це вже налаштовано.

Я вважаю за краще зберігати включені бібліотеки якомога непорочнішими, тому глобальна конфігурація shim один раз на сторінку здається мені найчистішим рішенням . Таким чином модернізація є більш безпечною, і CDN стають можливою.


1
Якщо я не роблю як дефініцію, так і шим, речі не працюють, я отримую $ .cookie не повідомлення про помилку функції
Нікола Пелучетті

На мій досвід, не повернення нічого з визначальної функції недостатньо, requirejs не розпізнає, що модуль завантажений. Це може розбудити shim: {plugins: {залежить: ['jquery'],
export

Зауважте, що сценарій плагіна jQuery повинен насправді працювати. Я не фахівець, але я знайшов прямолінійне рішення, згідно з яким у вас є один require(['plugin1', 'plugin2']);і т.д. Це означає, що вони потім додаватимуть себе, jQuery.fnтому скрізь ви можете просто вказати "jquery" як залежність, і вони будуть включені. Як я вже казав, я досить новачок у цьому, і може бути кращий підхід (наприклад, просто використання scriptтегу), але це працює.
Джошуа Бамбрік

3
Джош: Ви граєте в азартні ігри, що все завантажується в правильному порядку. Деякі користувачі вашого сайту, ймовірно, бачать зламані речі. Проблема полягає не стільки в тому, що плагін завантажується, а в тому, коли плагін завантажується, і в тому, що ще виконується на той момент. Основною причиною використання require є забезпечення розумного порядку операцій на основі залежностей, а не здогадок.
Ганс,

104

Є деякі застереження щодо використання конфігурації шима в RequireJS, на які вказується на http://requirejs.org/docs/api.html#config-shim . А саме: "Не змішуйте завантаження CDN із конфігурацією shim у збірці", коли ви використовуєте оптимізатор.

Я шукав спосіб використовувати той самий код плагіна 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. Я додав пояснення того, як це працює.
Carl Raymond

Будь-які поради щодо того, як це зробити та створити плагін, який працює з jQuery або Zepto? Ви могли б легко замінити код factory(jQuery || Zepto);, що не є AMD , але я не знаю, як ви зробили б частину AMD. Думаю, вам довелося б встановити jQuery "шлях" до zepto ?? paths: { jquery: 'vendor/zepto/zepto.min' }
Ryan Wheale

вау, я давно хотів зрозуміти цей фрагмент коду. Велике спасибі, чи не по shimсуті це робиться саме так? Я думаю, ні .. тому що ви сказали, що вручну кодуєте його, як вище.
Євген

Protip для таких ідіотів, як я: там, де написано $.fn.jqueryPluginу фрагменті, змініть jqueryPluginім'я плагіна !!
Метт Лейсі,

2

Подібно до того, як FYI для всіх плагінів jquery вже використовує amd / require, так що вам не потрібно нічого заявляти в шайбі. Насправді в деяких випадках це може створити для вас проблеми.

Якщо ви заглянете до файлу cookie jquery JS, ви побачите визначення викликів та вимог (["jquery"]).

і в jquery.js ви побачите виклик для визначення ("jquery", [], function () ...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.