2012-06-06 11 views
85

Sto lavorando con requirejs + jquery e mi chiedevo se ci fosse un modo intelligente per far funzionare bene un plugin jQuery con require.Come rendere un plugin jQuery caricabile con requirejs

Ad esempio sto utilizzando jQuery-cookie. Se ho capito bene che posso creare un file chiamato jquery-cookie.js e dentro fare

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"] 
    } 
}); 

mi sono chiesto se ho potuto fare le cose come jQuery fa, che è come questo:

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

o se questo è l'unico modo per rendere i plugin jQuery compatibile con requirejs o qualsiasi amd

risposta

66

Hai solo bisogno di effettuare una

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

alla fine di jQuery-cookie.js, OR

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

da nessuna parte prima di includere jquery-cookie (come ogniqualvolta punti dati-principale, ad esempio).

L'ultimo blocco di codice che hai postato è buono per cose come jQuery che vengono ridistribuite e possono o meno essere in un ambiente AMD. Idealmente, ogni plug-in di jQuery sarebbe già configurato.

Preferisco mantenere le librerie incluse nel modo più puro possibile, quindi la configurazione di shim globale una volta per pagina mi sembra la soluzione più pulita per me. In questo modo gli aggiornamenti sono più sicuri e le CDN diventano una possibilità.

+1

Se non faccio sia la definiscono e le cose shim non funzionano, ottengo $ .cookie non è un messaggio di errore di funzione –

+0

Secondo la mia esperienza, non restituire nulla dalla funzione di definizione non è sufficiente, requirejs non riconoscerà che il modulo è stato caricato.Questo può essere risolto da shim: { plugins: { dipende: ['jquery'], esportazioni: 'plugins' } – honzajde

+0

Si noti che lo script del plug-in jQuery deve essere effettivamente eseguito Non sono esperto ma ho trovato una soluzione semplice in cui si ha un singolo 'require ([ 'plugin1', 'plugi n2 ']); 'ecc. Non viene passata alcuna richiamata, quindi non verrà eseguito nulla tranne gli script del plugin stessi. Ciò significa che si aggiungeranno a 'jQuery.fn', quindi in qualsiasi altro modo è possibile elencare 'jquery' come dipendenza e saranno inclusi. Come ho già detto, sono abbastanza nuovo a questo e potrebbe esserci un approccio migliore (come l'uso di un tag 'script'), ma funziona. –

101

Ci sono alcuni avvertimenti con l'uso della configurazione shim in RequireJS, indicato su http://requirejs.org/docs/api.html#config-shim. Vale a dire, "Non mescolare il caricamento CDN con shim config in una build" quando si utilizza l'ottimizzatore.

Stavo cercando un modo per utilizzare lo stesso codice del plugin jQuery sui siti sia con che senza RequireJS. Ho trovato questo snippet per i plugin jQuery a https://github.com/umdjs/umd/blob/master/jqueryPlugin.js. Si avvolge il plugin in questo codice e funzionerà correttamente in entrambi i modi.

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

})); 

Il credito va a jrburke; come molto javascript, le sue funzioni all'interno di funzioni che agiscono su altre funzioni. Ma penso di aver disfatto ciò che sta facendo.

L'argomento della funzione factory nella prima riga è di per sé una funzione che viene richiamata per definire il plug-in sull'argomento $. Quando non è presente un caricatore compatibile con AMD, viene invocato direttamente per definire il plug-in sull'oggetto globale jQuery. Questo è proprio come il comune linguaggio definizione plugin:

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

Se c'è un caricatore modulo, quindi factory è registrato come il callback per il caricatore di invocare dopo aver caricato jQuery. La copia caricata di jQuery è l'argomento. E 'equivalente a

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

Mi piace questa risposta perché anche se la domanda riguardava un plugin jQuery, questo funziona per qualsiasi tipo di modulo o libreria, non solo per jQuery. Mi ci è voluto un minuto per avvolgere la mia mente sul tuo codice, ma una volta fatto, aveva perfettamente senso. –

+1

È javascript assolutamente impenetrabile. Ho aggiunto alcune spiegazioni su come funziona. –

+0

Qualche consiglio su come fare questo e creare un plugin che funzioni con jQuery *** o *** Zepto? Si potrebbe facilmente sostituire il codice non AMD con 'factory (jQuery || Zepto);', ma non so come si farebbe la parte AMD. Penso che dovresti impostare il "percorso" jQuery su zepto ?? 'percorsi: {jquery: 'vendor/zepto/zepto.min'}' –

2

Proprio come un FYI a tutti alcuni dei plugin jQuery già utilizzano AMD/richiedono quindi non avete bisogno di dichiarare nulla in spessore. In effetti, ciò potrebbe causare problemi in alcuni casi.

Se si guarda nel jquery cookie JS vedrete definire chiamate e richiedere (["jquery"]).

e in jquery.js vedrete una chiamata per definire ("jquery", [], la funzione() ...

Problemi correlati