आवश्यकता है कि क्यों और कब शिम विन्यास का उपयोग करना है


97

मैं यहाँ API से अपेक्षित दस्तावेज़ पढ़ता हूँ

requirejs.config({
    shim: {
        'backbone': {
            //These script dependencies should be loaded before loading
            //backbone.js
            deps: ['underscore', 'jquery'],
            //Once loaded, use the global 'Backbone' as the
            //module value.
            exports: 'Backbone'
        },
        'underscore': {
            exports: '_'
        },
        'foo': {
            deps: ['bar'],
            exports: 'Foo',
            init: function (bar) {
                //Using a function allows you to call noConflict for
                //libraries that support it, and do other cleanup.
                //However, plugins for those libraries may still want
                //a global. "this" for the function will be the global
                //object. The dependencies will be passed in as
                //function arguments. If this function returns a value,
                //then that value is used as the module export value
                //instead of the object found via the 'exports' string.
                return this.Foo.noConflict();
            }
        }
    }
});

लेकिन मैं नहीं मिल रहा है शिम इसका हिस्सा। मुझे शिम का उपयोग क्यों करना चाहिए और मुझे कैसे कॉन्फ़िगर करना चाहिए, क्या मुझे कुछ और स्पष्टीकरण मिल सकते हैं

कृपया कोई भी उदाहरण के साथ समझा सकता है कि हमें शिम का उपयोग क्यों और कब करना चाहिए। धन्यवाद।

जवाबों:


110

शिम का एक प्राथमिक उपयोग पुस्तकालयों के साथ है जो एएमडी का समर्थन नहीं करते हैं, लेकिन आपको उनकी निर्भरता का प्रबंधन करने की आवश्यकता है। उदाहरण के लिए, बैकबोन और अंडरस्कोर उदाहरण में ऊपर: आप जानते हैं कि बैकबोन को अंडरस्कोर की आवश्यकता होती है, इसलिए मान लीजिए कि आपने अपना कोड इस तरह लिखा है:

require(['underscore', 'backbone']
, function( Underscore, Backbone ) {

    // do something with Backbone

}

आवश्यकताएँJ अंडरस्कोर और बैकबोन दोनों के लिए अतुल्यकालिक अनुरोधों को बंद कर देंगे, लेकिन आप नहीं जानते कि कौन सा पहले वापस आएगा, इसलिए यह संभव है कि बैकबोन लोड होने से पहले अंडरस्कोर के साथ कुछ करने की कोशिश करेगा।

नोट: यह अंडरस्कोर / बैकबोन उदाहरण उन दोनों पुस्तकालयों द्वारा समर्थित एएमडी से पहले लिखा गया था। लेकिन सिद्धांत आज किसी भी पुस्तकालयों के लिए सही है जो एएमडी का समर्थन नहीं करते हैं।

"Init" हुक आपको अन्य उन्नत चीजें करने देता है, उदाहरण के लिए, यदि एक पुस्तकालय सामान्य रूप से दो अलग-अलग चीजों को वैश्विक नामस्थान में निर्यात करेगा, लेकिन आप उन्हें किसी एकल नाम स्थान के तहत पुनर्परिभाषित करना चाहते हैं। या, हो सकता है कि आप लाइब्रेरी में उन तरीकों पर कुछ बंदर पैचिंग करना चाहते हैं जिन्हें आप लोड कर रहे हैं।

अधिक पृष्ठभूमि:


जैसे आप उदाहरण कोड, Underscoreऔर Backboneयहाँ सामान्य की तरह उपयोग shimकरते हैं, इस मामले में क्या करना है? क्या मैं उपयोग कर सकता हूं require( function() { _.extend({}); })? क्या यह समझ में आता है _?
4

"EssentialJS अंडरस्कोर और बैकबोन दोनों के लिए अतुल्यकालिक अनुरोधों को बंद कर देगा" -> क्या इसे रोकने के लिए संभव है, इस मामले में कि पुस्तकालय पहले से ही लोड है?
कोडी

1
@ कोडी सही है, यदि पुस्तकालय पहले से ही भरा हुआ है तो यह दूसरे सर्वर अनुरोध को बंद नहीं करेगा, लेकिन आवश्यकता की बात यह है कि आपके कोड को इस बात की परवाह करने की आवश्यकता नहीं है कि क्या / कैसे होता है। शायद अपने विशेष उपयोग के मामले के लिए एक नया प्रश्न शुरू करें?
विस्फोट

63

आवश्यकता के अनुसार एपीआई प्रलेखन, शिम आपको देता है

निर्भरता, निर्यात, और पुराने, पारंपरिक "ब्राउज़र ग्लोबल्स" स्क्रिप्ट के लिए कस्टम आरंभीकरण कॉन्फ़िगर करें जो निर्भरता घोषित करने और मॉड्यूल मान सेट करने के लिए परिभाषित () का उपयोग नहीं करते हैं।

- निर्भरता को कॉन्फ़िगर करना

कहते हैं कि आपके पास 2 जावास्क्रिप्ट मॉड्यूल (मॉड्यूलए और मॉड्यूलबी) हैं और उनमें से एक (मॉड्यूलए) अन्य (मॉड्यूलबी) पर निर्भर करता है। ये दोनों आपके अपने मॉड्यूल के लिए आवश्यक हैं ताकि आप आवश्यकता में निर्भरता निर्दिष्ट करें () या परिभाषित ()

require(['moduleA','moduleB'],function(A,B ) {
    ...
}

लेकिन चूंकि खुद को एएमडी का पालन करने की आवश्यकता होती है, इसलिए आपको पता नहीं है कि कौन सा जल्दी लाया जाएगा। यह वह जगह है जहाँ शिम बचाव के लिए आता है।

require.config({
    shim:{
       moduleA:{
         deps:['moduleB']
        } 
    }

})

यह सुनिश्चित करेगा कि मॉड्यूलए लोड होने से पहले मॉड्यूलबी को हमेशा लाया जाए।

- निर्यात को कॉन्फ़िगर करना

शिम एक्सपोर्ट आवश्यकताएँ बताता है कि वैश्विक ऑब्जेक्ट (विंडो में, निश्चित रूप से आप एक ब्राउज़र में हैं) पर कौन सा सदस्य वास्तविक मॉड्यूल मान है। कहते हैं कि मॉड्यूलए खुद को window' मॉडा ' के रूप में जोड़ता है (जैसे कि jQuery और अंडरस्कोर क्रमशः $ और _ के रूप में करता है), तो हम अपने निर्यात मूल्य को 'मोडा' बनाते हैं।

require.config({
    shim:{
       moduleA:{
         exports:'modA'
        } 
    }

यह इस मॉड्यूल के लिए एक स्थानीय संदर्भ की आवश्यकता देगा। वैश्विक मोडा अभी भी पेज पर मौजूद होगा।

पुराने "ब्राउज़र ग्लोबल" स्क्रिप्ट्स के लिए कस्टम इनिशियलाइज़ेशन

यह शायद shim config की सबसे महत्वपूर्ण विशेषता है जो हमें अपने स्वयं के मॉड्यूल में निर्भरता के रूप में 'ब्राउज़र ग्लोबल', 'नॉन-एएमडी' स्क्रिप्ट (जो या तो मॉड्यूलर पैटर्न का पालन नहीं करता है) को जोड़ने की अनुमति देती है।

बता दें कि मॉड्यूलबी केवल दो फ़ंक्शन funcA () और funcB () के साथ सादे पुरानी जावास्क्रिप्ट है।

function funcA(){
    console.log("this is function A")
}
function funcB(){
    console.log("this is function B")
}

हालाँकि ये दोनों कार्य विंडो स्कोप में उपलब्ध हैं, फिर भी हमें सलाह देने के लिए आवश्यकताएँ जेएफएस अपने वैश्विक पहचानकर्ता / हैंडल के माध्यम से इनका उपयोग करने की सलाह देते हैं। इसलिए शिम को कॉन्फ़िगर करना

shim: {
    moduleB: {
        deps: ["jquery"],
        exports: "funcB",
        init: function () {
            return {
                funcA: funcA,
                funcB: funcB
            };
        }
    }
}

Init फ़ंक्शन से वापसी मान का उपयोग 'निर्यात' स्ट्रिंग के माध्यम से प्राप्त वस्तु के बजाय मॉड्यूल निर्यात मूल्य के रूप में किया जाता है। यह हमें अपने स्वयं के मॉड्यूल में funcB का उपयोग करने की अनुमति देगा

require(["moduleA","moduleB"], function(A, B){
    B.funcB()
})

आशा है कि इससे मदद मिली।


3
समझने में आसान! एक प्रश्न: पिछले उदाहरण में, "निर्यात" संपत्ति को केवल अनदेखा किया गया है?
निको बेलिक

नहीं, इसकी अनदेखी नहीं की जा रही है। यदि अंतिम उदाहरण में "निर्यात" संपत्ति को नजरअंदाज कर दिया गया था, तो आप जिस वस्तु को एक पैरामीटर के रूप में पास करते हैं ('बी' इस मामले में) अपरिभाषित होगा क्योंकि मॉड्यूलबी एएमडी अनुपालन नहीं है और जरूरी वस्तुओं का उपयोग करने के लिए वापस नहीं किया जाएगा (उपयोग करने के लिए) इसलिए 'B.funcB' काम नहीं करेगा)।
nalinc

हम्म। मुझे लगा कि निर्यात का मूल्य उस वस्तु द्वारा ओवररोड किया जाएगा जो इनिट फ़ंक्शन में वापस आ गया है। तो पैरामीटर B ऑब्जेक्ट {funcA: funcA, funcB: funcB} होगा, न कि केवल funcB के लिए। क्या यह सच नहीं है?
निको बेलिक

4
निको बेलिक सही है, निर्यात को अनदेखा किया गया है (मैंने अभी परीक्षण किया है)। ऑब्जेक्ट बी 'इनिट' भाग में निर्दिष्ट फ़ंक्शन द्वारा लौटाया गया ऑब्जेक्ट है। यदि आप 'init' भाग को हटा देते हैं, तो ऑब्जेक्ट B फ़ंक्शन funcB बन जाएगा, इसलिए आप B.funcB () के बजाय B () करेंगे। और जाहिर है कि funcA उस मामले में दुर्गम हो जाएगा।
user4205580

-2

आपको उदघोषणा के लिए जरुरी तरीके से रास्ता जोड़ना होगा, उदाहरण:

requirejs.config({
    paths: {
          'underscore' : '.../example/XX.js' // your JavaScript file
          'jquery' : '.../example/jquery.js' // your JavaScript file
    }
    shim: {
        'backbone': {
            deps: ['underscore', 'jquery'],
            exports: 'Backbone'
        },
        'underscore': {
            exports: '_'
        },
        'foo': {
            deps: ['bar'],
            exports: 'Foo',
            init: function (bar) {
                return this.Foo.noConflict();
            }
        }
    }
});

1
यह उत्तर एक कोड डंप है जो "क्यों और कब शिम कॉन्फिगर का उपयोग करता है" यह समझाने के लिए कुछ भी नहीं करता है। यदि आप स्पष्टीकरण देने के लिए अपने उत्तर को संपादित करते हैं, तो सुनिश्चित करें कि आप कुछ नया जोड़ रहे हैं, जो पहले से ही उत्तर द्वारा कवर नहीं किया गया है
लुई

कॉपी पेस्ट को बिना किसी सकारात्मक प्रतिक्रिया के
william.eyidi

शिम से पहले एक अल्पविराम होना चाहिए:
स्कॉट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.