2012-09-04 14 views
17

Piszę skrypt, który ma być osadzony w witrynach stron trzecich w celu dodania do nich funkcjonalności. Niedawno wyrzuciłem mój dość niechlujny kod niestandardowego programu ładującego i zacząłem zastępować go programem requirejs. Jedną z bibliotek, która opcjonalnie jest ładowana dla mnie (zależy od niektórych parametrów przekazywanych) jest jQuery.Make requireJs nie ponownie ładuje jQuery, jeśli już na stronie

Działa to dobrze, dopóki mój skrypt nie zostanie dołączony do strony, na której jQuery już jest, w którym to przypadku wydaje się, że niektóre wtyczki częściowo się wczytują, requirejs ładuje jQuery przez wersję strony, a wtyczki natychmiast się psują.

Pytanie klientów, aby przepisali swoje strony tylko po to, by użyć tego skryptu, nie wchodzi w grę, więc chciałbym wykryć, czy jQuery jest już załadowany, jeśli tak, to pominąć ładowanie go przez requirejs i po prostu użyć już załadowany jeden (Może to otworzyć mnie na przypadki i błędy o dziwnych krawędziach, gdy używają znacznie starszej wersji jQuery, ale nie mam dużego wyboru).

To, co myślałem, że zrobię, to napisanie nowego modułu, który najpierw sprawdzi, czy jQuery jest załadowany, jeśli jest, po prostu wyeksportuj obiekt jQuery, a jeśli nie, załaduj go, a następnie wyeksportuj. Jednak wydaje mi się, że jestem utrudniony, ponieważ funkcja definicji modułu wydaje się być synchroniczna do pracy, więc nie mogę wyjść i wczytać innego skryptu, który byłby asynchroniczny, a następnie załadować eksport do requirejs.

Czy brakuje mi czegoś w dokumentach? Czy to, co próbuję, uniemożliwia?

+0

Czy pomogłoby to [załadować dwie różne wersje jQuery w tym samym czasie] (http://stackoverflow.com/q/1566595/33732)? –

+0

To rozwiązałoby problemy z wersjami. Nie wydaje się to jednak rozwiązać problemu deptania wtyczek, ponieważ najprawdopodobniej wersja na stronie załaduje się przed moją kopią i nie będzie miała wpływu na noc. Przypuszczam, że mógłbym zmodyfikować obsługiwaną wersję jQuery, aby nie deptać obiektów $/jQuery, i po prostu ujawnić się jako moduł, ale wolałbym to zrobić jako ostatnią deskę ratunku, ponieważ wtedy musiałbym pamiętać, aby to zrobić zmienić po aktualizacji jQuery. –

+1

To nie powinno mieć znaczenia. Tylko jedna z bibliotek musi mieć świadomość trybu braku konfliktu.Kiedy wywołasz 'noConflict' na twojej kopii jQuery, wartości' $ 'i' jQuery' zostaną przywrócone do oryginałów, zanim załadowano twoją kopię. Wtyczki, które używały oryginalnej instancji, będą ją nadal odnosić. Oryginalna instancja jQuery przyjmie, że jest jedyną, która jest w porządku. –

Odpowiedz

26

Miałem ten sam problem w podobnym projekcie, używając require.js do biblioteki, która ma być załadowana na strony innych firm. Można zobaczyć moje podejście here, ale tutaj jest uproszczona wersja:

// 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 

}); 

Jak widać, to wygląda na jQuery, a następnie albo określa moduł „jquery” jako otoczka do istniejącej biblioteki, lub (jeśli nie ma jQuery lub jeśli istniejący jQuery jest starszą wersją) ładuje jQuery specyficzną dla biblioteki za pomocą noConflict.

To działa całkiem dobrze. Jedynym minusem jest dynamiczne wywoływanie w skrypcie require(), co utrudnia efektywne używanie optymalizatora r.js.

+0

Ładny kod. Wyrażenie oldjQuery nie działa jednak dla jQuery> = 1.10. – Chris

+1

Dzięki, @Chris - zaktualizowano wyrażenie regularne. – nrabinowitz

+0

Mam podobne pytanie tutaj http://stackoverflow.com/questions/20291793/adding-requirejs-module-that-us-jquery-on-a-page-that-already-has-jquery-as-a. Jak nie używać "mapy", jak sugeruje to API? Co byś zrobił, gdybyś chciał załadować trzecią wersję jquery do innego modułu? – gillyspy

3

miałem podobny problem .. Mój skrypt został przeładunkowy dwukrotnie jQuery .. wykorzystał rozwiązanie z uwagi na this article

pracował jak czar !!

(Komentarz który pracował był:

"I umieścić go na moim pliku konfiguracyjnego po requirejs.config (...), a przed requirej ([" app "]) i to działało")

+1

Znacznie prostsze niż zaakceptowana odpowiedź – LostInComputer

Powiązane problemy