2015-09-09 9 views
14

एक से अधिक संस्करण लोड हो रहा है मेरी वेबसाइट पर मैं सबसे जावास्क्रिप्ट RequireJs एसिंक्रोनस रूप का उपयोग करके लोड। निम्नलिखितRequireJs मुद्दा जब jQuery

require(['DisplayAccordion']); 

कहाँ DisplayAccordion.js शामिल:

require.config({ 
    paths: { 
     'jquery': '//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery' 
    }, 
    shim: { 
     'jquery.accordion': { 
      deps: ['jquery'] 
     } 
    } 
}); 

मैं निम्नलिखित कोड शरीर के भीतर परिभाषित एक फ़ाइल एसिंक्रोनस रूप से लोड करने के लिए है कहते हैं: कृपया मेरे RequireJs विन्यास के लिए निम्न देखें

define(['jquery', 'jquery.accordion'], function($) { 
    $(function() { 
     $('.xyz').accordion(); 
    }); 
}); 

नोट: jquery.accordion बस एक jQuery प्लगइन है जिसमें एएमडी समर्थन नहीं है और वैश्विक jQuery चर परिभाषित करने की आवश्यकता है।

यह ठीक काम करता है, लेकिन अब कहते हैं कि मैं एक तीसरी पार्टी पुस्तकालय करने के लिए अपने पृष्ठ पर एक स्क्रिप्ट संदर्भ छोड़ देते हैं। उदाहरण के लिए:

<script src="//example.com/ThirdParty.js"></script> 

जहां तीसरी पार्टी लाइब्रेरी jQuery का अपना संस्करण लोड करती है। अब मैं त्रुटि हो रही है:

Object doesn't support property or method 'accordion'.

कोड मैंने पाया कि यह निम्न क्रम में कार्यान्वित के माध्यम से कदम के बाद:

  1. ThirdParty.js
  2. jquery.min.js - तीसरे पक्ष के संस्करण
  3. jquery.min.js - मेरी संस्करण
  4. jquery.accordion.js - जहां jQuery
  5. Displ की मेरी संस्करण संदर्भ के लिए $ अंक ayAccordion.js (कॉलबैक फ़ंक्शन) - जहां jQuery

पर तीसरे पक्ष संस्करण के लिए $ अंक अब मैं देख सकता हूं कि मुझे त्रुटि क्यों मिलती है क्योंकि प्लगइन किसी भिन्न ऑब्जेक्ट से जुड़ा हुआ है। हालांकि मुझे यकीन है कि क्यों यह इस करना होगा नहीं कर रहा हूँ।

नीचे दी गई जानकारी बस समझाएगी कि $ .noConflict (true) का उपयोग क्यों नहीं करेगा।

मुद्दे पर कुछ शोध करने के बाद। मैं अपने config संशोधित:

require.config({ 
    paths: { 
     'jquery': '//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery' 
    }, 
    map: { 
     '*': { 'jquery': 'jquery-private' }, 
     'jquery-private': { 'jquery': 'jquery' } 
    }, 
    shim: { 
     'jquery.accordion': { 
      deps: ['jquery'] 
     } 
    } 
}); 

कहाँ jQuery-private.js के रूप में परिभाषित किया गया है:

define(['jquery'], function($) { 
    return $.noConflict(true); 
}); 

कृपया ध्यान दें कि इस http://www.requirejs.org/docs/jquery.html#noconflictmap

अब यह निम्न क्रम में कार्यान्वित से लिया गया है:

  1. ThirdParty.js
  2. jquery.min.js - तीसरे पक्ष के संस्करण
  3. jQuery-private.js (कॉलबैक फ़ंक्शन)
  4. jquery.min.js - मेरी संस्करण
  5. jquery.accordion.js - जहां $ अपरिभाषित है
  6. DisplayAccordion ।js (कॉलबैक फ़ंक्शन) - जहां के तीसरे पक्ष के संस्करण jQuery के लिए $ अंक

आप कल्पना कर सकते हैं यह या तो काम नहीं के बाद से $ jquery.accordion.js फ़ाइल के भीतर अपरिभाषित है।

$.noConflict(true); 

मुझे लगता है कि मैं समझता हूँ कि यहाँ क्या हो रहा है:

आगे डिबगिंग की abit बाद मैं तीसरे पक्ष के पुस्तकालय भी कहता है की खोज की। जब यह तीसरे पक्ष की लाइब्रेरी में $ .noConflict (true) को कॉल करता है तो यह वैश्विक संस्करण $ और jQuery को पिछले संस्करण में सेट करने का प्रयास करता है। हालांकि चूंकि कोई पिछले संस्करण लोड नहीं हुआ है, यह अपरिभाषित पर सेट है।

अब जब यह jquery-private.js को कॉल करता है और $ देता है .noConflict (true) यह वैश्विक jQuery चर वापस लौटाएगा जिसे अपरिभाषित करने के लिए सेट किया गया है। हालांकि अब यह वैश्विक jQuery चर पुस्तकालय के तीसरे पक्ष संस्करण में सेट करेगा।

तो जब यह jquery.accordion $ लोड करता है तो अपरिभाषित होता है। लेकिन जब यह अगला DisplayAccordion.js को कॉल करता है तो यह अब jQuery लाइब्रेरी के तीसरे पक्ष संस्करण का संदर्भ दे रहा है।

अगर कोई फिक्स सुझा सकता है तो मैं इसकी सराहना करता हूं। धन्यवाद

उत्तर

1

मैं सुझाव देंगे आप jquery.accordion.js के अपने स्वयं के संस्करण बनाने - एक RequireJS मॉड्यूल में यह कर रही है (एक define(["jquery-private"], function($){ ... }); आदि में लपेट)

बाकी सब कुछ jquery-private बजाय jquery के लिए पूछने की जरूरत है - इसलिए का require()/define() कॉल का केवल उल्लेख jquery-private में होगा।

हालांकि इसका मतलब यह नहीं होगा कि इसे किसी तृतीय पक्ष ऑटो-अपडेटेड सीडीएन से लोड करने में सक्षम न हो, यह इसे jQuery के "उचित" संस्करण पर चलाने देगा।

इस बीच (यदि आप जानते हैं कि यह कौन सा है - गिटहब उस नाम की कई परियोजनाओं को सूचीबद्ध करता है) तो आप इसे आवश्यकतानुसार सक्षम करने के लिए गिटहब को एक बग रिपोर्ट/पुल अनुरोध भी सबमिट कर सकते हैं - फिर अपडेट होने के बाद पथ को बदलें :-)

+0

इससे समस्या ठीक नहीं होगी। ध्यान दें कि ओपी के प्रयास (दोनों प्रयासों) के अंतिम चरण में, 'डिस्प्लेएक्ॉर्डियन' मॉड्यूल, जो * मॉड्यूल के रूप में * jquery' लोड करता है, ओपी चाहता है संस्करण के बजाए jQuery का तीसरा पक्ष संस्करण प्राप्त करता है। आप यहां जो सुझाव देते हैं वह वही काम करेगा: 'jquery.accordion' को ओपी चाहता है की बजाय jQuery का तीसरा पक्ष संस्करण मिलेगा। अगर मेरे उत्तर में समझाया गया तो ऐसा क्यों होता है। – Louis

+0

दोह - मैं देखता हूं - आपके उत्तर में बड़ी समस्या यह है कि यह इस तथ्य को अनदेखा करता है कि ओपी के पास लोड ऑर्डर का कोई नियंत्रण नहीं है (यही कारण है कि यह सूचनात्मक के अलावा किसी अन्य तरीके से मदद नहीं करता है)। 'Jquery' के बजाय 'jquery-private' मॉड्यूल का उपयोग करने के बारे में - इसे अभी भी लिपटे होने के लिए एग्रीजन की आवश्यकता होगी, लेकिन सही संस्करण का उपयोग किया जाना चाहिए ... – Rycochet

+0

' jquery-private' का उपयोग करना समस्या को ठीक नहीं करेगा । प्रश्न में दूसरे प्रयास में ओपी ने यही किया। जैसा कि मैंने अपनी पिछली टिप्पणी में इंगित किया था, * * * प्रयास * प्रदर्शन 'निष्पादन' में गलत संस्करण मिलता है। मेरे उत्तर के मूल्य के लिए, हां, मैंने ओपी की टिप्पणी पढ़ी है और महसूस किया है कि यह काम नहीं करेगा अगर 'थर्डपार्टी.जेएस' से संबंधित ओपी के कोड का लोड ऑर्डर बाधित नहीं किया जा सकता है। रिकॉर्ड के लिए, ओपी ने * महत्वपूर्ण * चेतावनी को जोड़ा कि लोड ऑर्डर पर कोई नियंत्रण नहीं है * * मैंने अपना उत्तर पोस्ट किया है। किसी भी दर पर, मेरे लिए यह इंगित करता है कि आदेश को बाधित किया जाना चाहिए। – Louis

1

एकमात्र तरीका जो मैं शुरू में हो रहा व्यवहार देख सकता हूं, यदि आप ThirdParty.js लोडजेएस लोड होने के बाद लोड करते हैं। यहां क्या होता है:

  1. RequJS लोड हो गया है।

  2. ThirdParty.js भार।

  3. jquery.min.js तृतीय पक्ष संस्करण लोड। यह जांचता है कि define.amd मौजूद है या नहीं। ऐसा करता है, इसलिए यह define('jquery', ... पर कॉल करता है और एएमडी मॉड्यूल के रूप में पंजीकृत होता है।

  4. jquery.min.js आपका संस्करण लोड करता है। आपको आश्चर्य हो सकता है कि 0Jपहले से ही परिभाषित होने पर RequJS को लोड करने से परेशान क्यों होगा। हम यहां दौड़ की स्थिति से निपट रहे हैं। यदि चरण 3 से पहले jquery की लोडिंग को ट्रिगर करने के लिए कुछ भी है, तो मुझे उम्मीद है कि RequJS को jQuery के आपके संस्करण का बेकार लोड शेड्यूल करना होगा। define('jquery', ... फिर से कॉल किया जाएगा लेकिन पहले कॉल के कारण कुछ भी नहीं करेगा।

  5. jquery.accordion.js निष्पादन, जहां $ jQuery के आपके संस्करण को इंगित करता है। हां, क्योंकि चरण 4 में, वैश्विक $ आपके संस्करण पर सेट किया गया था।

  6. DisplayAccordion.js निष्पादन, जहां $ jQuery के तीसरे पक्ष संस्करण को इंगित करता है। हां, क्योंकि चरण 3 में, यह एक तृतीय पक्ष संस्करण है जो मॉड्यूल के रूप में पंजीकृत है।

इसे ठीक करने के, मैं उस ThirdParty.js और RequireJS से पहले jQuery लोड के अपने संस्करण के लिए सुनिश्चित हो जाएगा। आप इसे कैसे प्राप्त करते हैं इस पर निर्भर करता है कि कैसे ThirdParty.js jQuery लोड करता है। चूंकि ThirdParty.js$.noConflict पर कॉल करता है, तो इसके बाद आपको अपना कोड लोड करने और हस्तक्षेप नहीं होने के बाद ठीक होना चाहिए।

+1

धन्यवाद मैं भूल गया कि jQuery ने उस छोटे से नीचे थोड़ा परिभाषित किया था। दुर्भाग्यवश आपका सुझाया गया फ़िक्स संभव नहीं है क्योंकि यह कोड सामग्री प्रबंधन प्रणाली का हिस्सा है और मेरा ग्राहक पृष्ठ के मुख्य भाग में कहीं भी तीसरे पक्ष की स्क्रिप्ट छोड़ सकता है। – nfplee

संबंधित मुद्दे