2012-09-04 11 views
17

Estoy escribiendo un script que debe incrustarse en sitios de terceros para agregarles funcionalidad. Recientemente arranqué mi código de cargador personalizado bastante desordenado y comencé a reemplazarlo con requirejs. Una de las bibliotecas que opcionalmente se carga para mí (depende de algunos parámetros ingresados) es jQuery.Hacer que no se vuelva a cargar JQuery si ya está en la página

Esto funciona bien, hasta que mi script esté incluido en una página que ya tiene jQuery, en cuyo caso, lo que parece suceder es que algunos complementos se cargan parcialmente, requieren jQuery sobre la versión de la página y los complementos se rompen rápidamente.

No se puede pedir a los clientes que reescriban sus páginas solo para utilizar este script, así que lo que me gustaría hacer es detectar si jQuery ya está cargado, si es así, saltearlo mediante requirejs, y simplemente usar el ya cargado uno (Esto posiblemente me abra a casos e inconvenientes de bordes impares cuando están usando una versión mucho más antigua de jQuery, pero no tengo muchas opciones).

Lo que pensé que iba a hacer es escribir un nuevo módulo, que primero vería si jQuery está cargado, si es así, solo exporte el objeto jQuery, si no lo está, luego cárguelo y luego realice la exportación. Sin embargo, parezco estar bloqueado, ya que la función de definición para el módulo parece tener que ser síncrona para funcionar, por lo que no puedo apagar y cargar otro script, que sería asíncrono, luego rellenar la exportación en requirejs.

¿Me falta algo en los documentos? ¿Es lo que estoy intentando imposible?

+0

¿Ayudaría poder [cargar dos versiones diferentes de jQuery al mismo tiempo] (http://stackoverflow.com/q/1566595/33732)? –

+0

Eso resolvería los problemas de control de versiones. Sin embargo, esto no parece resolver el problema del plugin, ya que es muy probable que la versión en la página se cargue antes que la mía y no tenga ningún conflicto. Supongo que podría modificar mi versión servida de jQuery para no pisotear los objetos $/jQuery, y solo exponerme como un módulo, pero preferiría hacerlo como último recurso, ya que entonces tendría que recordar hacer eso cambiar cuando actualizo jQuery. –

+1

Eso no debería importar. Solo una de las bibliotecas debe conocer el modo sin conflicto.Cuando llama a 'noConflict' en su copia de jQuery, los valores de' $ 'y' jQuery' se restauran a los originales, desde antes de que se cargara su copia. Los complementos que utilizaron la instancia original seguirán refiriéndose a ella. La instancia original de jQuery asumirá que es la única, lo cual está bien. –

Respuesta

26

Tuve el mismo problema en un proyecto similar, usando require.js para una biblioteca destinada a ser cargada en sitios de terceros. Usted puede ver mi enfoque here, pero aquí está la versión simplificada:

// check for existing jQuery 
var jQuery = window.jQuery, 
    // check for old versions of jQuery 
    oldjQuery = jQuery && !!jQuery.fn.jquery.match(/^1\.[0-4](\.|$)/), 
    localJqueryPath = libPath + 'jquery/jquery-1.7.2.min', 
    paths = {}, 
    noConflict; 

// check for jQuery 
if (!jQuery || oldjQuery) { 
    // load if it's not available or doesn't meet min standards 
    paths.jquery = localJqueryPath; 
    noConflict = !!oldjQuery; 
} else { 
    // register the current jQuery 
    define('jquery', [], function() { return jQuery; }); 
} 

// set up require 
require.config({ 
    paths: paths 
}); 

// load stuff 
require(['jquery', ... ], function($, ...) { 

    // deal with jQuery versions if necessary 
    if (noConflict) $.noConflict(true); 

    // etc 

}); 

Como se puede ver, esto se ve para jQuery, y luego o bien define el módulo "jQuery" como un contenedor para la biblioteca existente, o (si no hay jQuery o si el jQuery existente es una versión anterior) carga el jQuery específico de la biblioteca con noConflict.

Esto funciona bastante bien. El único inconveniente es que está llamando al require() de forma dinámica dentro de su secuencia de comandos, lo que hace que sea más difícil utilizar el optimizador r.js de manera efectiva.

+0

Buen código. La vieja expresión regular de jQuery no funciona para jQuery> = 1.10 embargo. – Chris

+1

Gracias, @Chris - regex actualizada. – nrabinowitz

+0

tengo una pregunta similar aquí http://stackoverflow.com/questions/20291793/adding-requirejs-module-that-uses-jquery-on-a-page-that-already-has-jquery-as-a. ¿Cómo no usas un 'mapa' como se sugiere en la API? ¿Qué harías si quisieras cargar una tercera versión de jquery para otro módulo? – gillyspy

3

tuve un problema similar .. Mi guión fue recargando jQuery dos veces .. Se utiliza la solución de los comentarios en this article

Trabajó como un encanto !!

(comentario a la que impulsó fue:

"Me puso en mi archivo de configuración después de la requirejs.config (...) y antes de la requirej ([" aplicación "]) y funcionó")

+1

Mucho más simple que la respuesta aceptada – LostInComputer

Cuestiones relacionadas