RequireJS



requirejs

RequJS एपीआई

प्रयोग

जावास्क्रिप्ट फ़ाइलें लोड करें

RequjS पारंपरिक <script> टैग की तुलना में स्क्रिप्ट लोडिंग के लिए एक अलग दृष्टिकोण लेता है। हालांकि यह तेजी से चला सकता है और अच्छी तरह अनुकूलित कर सकता है, प्राथमिक लक्ष्य मॉड्यूलर कोड को प्रोत्साहित करना है। इसके हिस्से के रूप में, यह स्क्रिप्ट टैग के लिए यूआरएल के बजाय मॉड्यूल आईडी का उपयोग करने को प्रोत्साहित करता है।

RequJS बेसयूआरएल के सापेक्ष सभी कोड लोड करता है। बेसयूआरएल सामान्य रूप से एक ही निर्देशिका में सेट होता है जैसे पृष्ठ के लिए लोड करने के लिए शीर्ष स्तरीय स्क्रिप्ट के लिए डेटा-मुख्य विशेषता में उपयोग की जाने वाली स्क्रिप्ट। डेटा-मुख्य विशेषता एक विशेष विशेषता है जिसके लिए आवश्यक है .js स्क्रिप्ट लोडिंग शुरू करने के लिए जांच करेगा। यह उदाहरण स्क्रिप्ट के आधार URL के साथ समाप्त होगा:

<!--This sets the baseUrl to the "scripts" directory, and
    loads a script that will have a module ID of 'main'-->
<script data-main="scripts/main.js" src="scripts/require.js"></script>

या, baseUrl को RequJS कॉन्फ़िगरेशन के माध्यम से मैन्युअल रूप से सेट किया जा सकता है। यदि कोई स्पष्ट कॉन्फ़िगर नहीं है और डेटा-मुख्य का उपयोग नहीं किया जाता है, तो डिफ़ॉल्ट baseUrl वह निर्देशिका है जिसमें HTML पृष्ठ चल रहा है RequJS।

RequJS डिफ़ॉल्ट रूप से मानता है कि सभी निर्भरता स्क्रिप्ट हैं, इसलिए यह मॉड्यूल आईडी पर पिछला ".js" प्रत्यय देखने की अपेक्षा नहीं करता है। पथ में मॉड्यूल आईडी का अनुवाद करते समय RequJS स्वचालित रूप से इसे जोड़ देगा। पथ कॉन्फ़िगरेशन के साथ , आप स्क्रिप्ट के समूह के स्थान सेट अप कर सकते हैं। इन सभी क्षमताओं से आप परंपरागत <script> टैग की तुलना में स्क्रिप्ट के लिए छोटे तारों का उपयोग करने की अनुमति देते हैं।

ऐसे समय हो सकते हैं जब आप सीधे एक स्क्रिप्ट का संदर्भ लेना चाहते हैं और इसे खोजने के लिए "baseUrl + पथ" नियमों के अनुरूप नहीं हैं। यदि एक मॉड्यूल आईडी में निम्नलिखित विशेषताओं में से एक है, तो आईडी "baseUrl + पथ" कॉन्फ़िगरेशन के माध्यम से पारित नहीं की जाएगी, और दस्तावेज़ के सापेक्ष एक नियमित URL की तरह व्यवहार किया जाएगा:

  • ".js" में समाप्त होता है।
  • एक "/" के साथ शुरू होता है।
  • एक यूआरएल प्रोटोकॉल होता है, जैसे "http:" या "https:"।

सामान्य रूप से, मॉड्यूल आईडी के लिए पथ सेट करने के लिए बेसयूआरएल और "पथ" कॉन्फ़िगरेशन का उपयोग करना सबसे अच्छा है। ऐसा करके, यह ऑप्टिमाइज़ेशन बिल्ड के लिए विभिन्न स्थानों पर पथों का नाम बदलने और कॉन्फ़िगर करने में आपको अधिक लचीलापन देता है।

इसी तरह, कॉन्फ़िगरेशन के समूह से बचने के लिए, स्क्रिप्ट के लिए गहरे फ़ोल्डर पदानुक्रमों से बचने के लिए सबसे अच्छा है, और इसके बजाय बेस स्प्रिंग में सभी स्क्रिप्ट रखें, या यदि आप अपने ऐप कोड से अपनी लाइब्रेरी / विक्रेता-आपूर्ति कोड को अलग करना चाहते हैं, तो निर्देशिका लेआउट इस तरह:

  • www /
    • index.html
    • जे एस /
      • एप्लिकेशन /
        • sub.js
      • lib /
        • jquery.js
        • canvas.js
      • app.js
      • require.js

index.html में:

<script data-main="js/app.js" src="js/require.js"></script>

और app.js में:

requirejs.config({
    //By default load any module IDs from js/lib
    baseUrl: 'js/lib',
    //except, if the module ID starts with "app",
    //load it from the js/app directory. paths
    //config is relative to the baseUrl, and
    //never includes a ".js" extension since
    //the paths config could be for a directory.
    paths: {
        app: '../app'
    }
});

// Start the main app logic.
requirejs(['jquery', 'canvas', 'app/sub'],
function   ($,        canvas,   sub) {
    //jQuery, canvas and the app/sub module are all
    //loaded and can be used here now.
});

उस उदाहरण के हिस्से के रूप में नोटिस, jQuery जैसे विक्रेता पुस्तकालयों में उनके संस्करण नामों में उनके संस्करण संख्या नहीं थी। यदि आप इसे ट्रैक करना चाहते हैं, तो उस संस्करण की जानकारी को एक अलग पाठ फ़ाइल में संग्रहीत करने की अनुशंसा की जाती है, या यदि आप volo जैसे टूल का उपयोग करते हैं, तो यह संस्करण जानकारी के साथ package.json को मुद्रित करेगा लेकिन फ़ाइल को डिस्क पर "jquery" के रूप में रखेगा। js "। यह आपको प्रत्येक लाइब्रेरी के लिए "पथ" कॉन्फ़िगरेशन में प्रवेश करने की बजाय बहुत कम कॉन्फ़िगरेशन प्राप्त करने की अनुमति देता है। उदाहरण के लिए, "jquery" को "jquery-1.7.2" कॉन्फ़िगर करें।

आदर्श रूप से आपके द्वारा लोड की जाने वाली स्क्रिप्ट मॉड्यूल होंगी जिन्हें परिभाषित () को कॉल करके परिभाषित किया गया है। हालांकि, आपको कुछ पारंपरिक / विरासत "ब्राउज़र ग्लोबल्स" स्क्रिप्ट का उपयोग करने की आवश्यकता हो सकती है जो परिभाषित () के माध्यम से अपनी निर्भरताओं को व्यक्त नहीं करते हैं। उन लोगों के लिए, आप शिम कॉन्फ़िगरेशन का उपयोग कर सकते हैं। अपनी निर्भरताओं को सही ढंग से व्यक्त करने के लिए।

यदि आप निर्भरताओं को व्यक्त नहीं करते हैं, तो आपको संभावित लोडिंग त्रुटियां मिलेंगी क्योंकि RequJS स्क्रिप्ट को असीमित रूप से लोड करता है और गति के लिए आदेश से बाहर होता है।

डेटा-मुख्य प्रविष्टि बिंदु

डेटा-मुख्य विशेषता एक विशेष विशेषता है जिसके लिए आवश्यक है। जेएस स्क्रिप्ट लोडिंग शुरू करने के लिए जांच करेगा:

<!--when require.js loads it will inject another script tag
    (with async attribute) for scripts/main.js-->
<script data-main="scripts/main" src="scripts/require.js"></script>

कॉन्फ़िगरेशन विकल्पों को सेट करने के लिए आप आमतौर पर डेटा-मुख्य स्क्रिप्ट का उपयोग करेंगे और फिर पहला एप्लिकेशन मॉड्यूल लोड करेंगे। नोट: स्क्रिप्ट टैग requ.js आपके डेटा-मुख्य मॉड्यूल के लिए उत्पन्न करता है async विशेषता शामिल है । इसका अर्थ यह है कि आप यह नहीं मान सकते कि आपके डेटा-मुख्य स्क्रिप्ट का लोड और निष्पादन उसी पृष्ठ में बाद में संदर्भित अन्य स्क्रिप्ट से पहले समाप्त हो जाएगा।

उदाहरण के लिए, यह व्यवस्था यादृच्छिक रूप से विफल हो जाएगी जब 'foo' मॉड्यूल के लिए require.config पथ की आवश्यकता होने से पहले सेट नहीं किया गया है () 'd' बाद में:

<script data-main="scripts/main" src="scripts/require.js"></script>
<script src="scripts/other.js"></script>
// contents of main.js:
require.config({
    paths: {
        foo: 'libs/foo-1.1.3'
    }
});
// contents of other.js:

// This code might be called before the require.config() in main.js
// has executed. When that happens, require.js will attempt to
// load 'scripts/foo.js' instead of 'scripts/libs/foo-1.1.3.js'
require(['foo'], function(foo) {

});

यदि आप HTML पृष्ठ में कॉल require() कॉल करना चाहते हैं, तो डेटा-मुख्य का उपयोग करना सबसे अच्छा है। डेटा-मुख्य केवल तभी उपयोग के लिए होता है जब पृष्ठ में केवल एक मुख्य प्रविष्टि बिंदु होता है, डेटा-मुख्य स्क्रिप्ट। उन पृष्ठों के लिए जो इनलाइन करना चाहते हैं require() कॉल, कॉन्फ़िगरेशन के लिए कॉल require() कॉल के अंदर उन लोगों को घोंसला करना सबसे अच्छा है:

<script src="scripts/require.js"></script>
<script>
require(['scripts/config'], function() {
    // Configuration loaded now, safe to do other require calls
    // that depend on that config.
    require(['foo'], function(foo) {

    });
});
</script>

एक मॉड्यूल परिभाषित करें

एक मॉड्यूल एक पारंपरिक स्क्रिप्ट फ़ाइल से अलग है जिसमें यह एक अच्छी तरह से स्कॉप्ड ऑब्जेक्ट को परिभाषित करता है जो वैश्विक नामस्थान को प्रदूषित करने से बचाता है। यह स्पष्ट रूप से अपनी निर्भरताओं को सूचीबद्ध कर सकता है और वैश्विक वस्तुओं को संदर्भित किए बिना उन निर्भरताओं पर एक संभाल ले सकता है, लेकिन इसके बजाय निर्भरता को उस कार्य के तर्क के रूप में प्राप्त करता है जो मॉड्यूल को परिभाषित करता है। RequJS में मॉड्यूल मॉड्यूल पैटर्न का विस्तार है, अन्य मॉड्यूल के संदर्भ में ग्लोबल्स की आवश्यकता नहीं होने के लाभ के साथ।

मॉड्यूल के लिए RequJS वाक्यविन्यास उन्हें यथासंभव तेज़ी से लोड करने की अनुमति देता है, यहां तक ​​कि आदेश के बाहर भी, लेकिन सही निर्भरता क्रम में मूल्यांकन किया जाता है, और चूंकि वैश्विक चर नहीं बनाए जाते हैं, इसलिए यह पृष्ठ में मॉड्यूल के एकाधिक संस्करणों को लोड करना संभव बनाता है ।

(यदि आप कॉमनजेएस मॉड्यूल से परिचित हैं या उपयोग कर रहे हैं, तो कृपया आवश्यकता के लिए कॉमनजेएस नोट्स को भी देखें कि कैसे RequJS मॉड्यूल प्रारूप कॉमनजेएस मॉड्यूल को मानचित्र करता है)।

डिस्क पर प्रति फ़ाइल केवल एक मॉड्यूल परिभाषा होनी चाहिए। मॉड्यूल को ऑप्टिमाइज़ेशन टूल द्वारा अनुकूलित बंडलों में समूहीकृत किया जा सकता है।

सरल नाम / मूल्य जोड़े

यदि मॉड्यूल में कोई निर्भरता नहीं है, और यह सिर्फ नाम / मूल्य जोड़े का संग्रह है, तो बस परिभाषित करने के लिए एक ऑब्जेक्ट शाब्दिक पास करें ():

//Inside file my/shirt.js:
define({
    color: "black",
    size: "unisize"
});

परिभाषा कार्य

यदि मॉड्यूल में निर्भरता नहीं है, लेकिन कुछ सेटअप कार्य करने के लिए फ़ंक्शन का उपयोग करने की आवश्यकता है, तो स्वयं को परिभाषित करें, परिभाषित करने के लिए फ़ंक्शन पास करें ():

//my/shirt.js now does setup work
//before returning its module definition.
define(function () {
    //Do setup work here

    return {
        color: "black",
        size: "unisize"
    }
});

निर्भरता के साथ परिभाषा कार्य

यदि मॉड्यूल निर्भरता है, तो पहला तर्क निर्भरता नामों की एक सरणी होनी चाहिए, और दूसरा तर्क परिभाषा फ़ंक्शन होना चाहिए। सभी निर्भरताओं को लोड होने के बाद फ़ंक्शन को मॉड्यूल को परिभाषित करने के लिए कहा जाएगा। फ़ंक्शन को उस ऑब्जेक्ट को वापस करना चाहिए जो मॉड्यूल को परिभाषित करता है। निर्भरता फ़ंक्शन तर्क के रूप में परिभाषा फ़ंक्शन में पारित की जाएगी, निर्भरता सरणी में क्रम के रूप में उसी क्रम में सूचीबद्ध:

//my/shirt.js now has some dependencies, a cart and inventory
//module in the same directory as shirt.js
define(["./cart", "./inventory"], function(cart, inventory) {
        //return an object to define the "my/shirt" module.
        return {
            color: "blue",
            size: "large",
            addToCart: function() {
                inventory.decrement(this);
                cart.add(this);
            }
        }
    }
);

इस उदाहरण में, मेरा / शर्ट मॉड्यूल बनाया गया है। यह मेरे / कार्ट और मेरी / सूची पर निर्भर करता है। डिस्क पर, फाइलें इस तरह संरचित हैं:

  • मेरे / cart.js
  • मेरे / inventory.js
  • मेरे / shirt.js

उपरोक्त फ़ंक्शन कॉल दो तर्क, "कार्ट" और "सूची" निर्दिष्ट करता है। ये "./cart" और "./inventory" मॉड्यूल नामों द्वारा प्रदर्शित मॉड्यूल हैं।

फ़ंक्शन को तब तक नहीं कहा जाता है जब तक कि मेरे / कार्ट और मेरे / इन्वेंट्री मॉड्यूल लोड नहीं किए जाते हैं, और फ़ंक्शन को मॉड्यूल "कार्ट" और "इन्वेंट्री" तर्क के रूप में प्राप्त होता है।

ग्लोबल्स को परिभाषित करने वाले मॉड्यूल स्पष्ट रूप से निराश होते हैं, ताकि एक समय में एक मॉड्यूल के कई संस्करण मौजूद हो सकें ( उन्नत उपयोग देखें)। साथ ही, फ़ंक्शन तर्कों का क्रम निर्भरताओं के क्रम से मेल खाना चाहिए।

फ़ंक्शन कॉल से वापसी ऑब्जेक्ट "मेरा / शर्ट" मॉड्यूल परिभाषित करता है। इस तरह से मॉड्यूल को परिभाषित करके, "मेरी / शर्ट" वैश्विक वस्तु के रूप में मौजूद नहीं है।

एक मॉड्यूल को एक समारोह के रूप में परिभाषित करें

मॉड्यूल को वस्तुओं को वापस करने की ज़रूरत नहीं है। किसी फ़ंक्शन से किसी भी वैध वापसी मान की अनुमति है। यहां एक मॉड्यूल है जो फ़ंक्शन को इसकी मॉड्यूल परिभाषा के रूप में देता है:

//A module definition inside foo/title.js. It uses
//my/cart and my/inventory modules from before,
//but since foo/title.js is in a different directory than
//the "my" modules, it uses the "my" in the module dependency
//name to find them. The "my" part of the name can be mapped
//to any directory, but by default, it is assumed to be a
//sibling to the "foo" directory.
define(["my/cart", "my/inventory"],
    function(cart, inventory) {
        //return a function to define "foo/title".
        //It gets or sets the window title.
        return function(title) {
            return title ? (window.title = title) :
                   inventory.storeName + ' ' + cart.name;
        }
    }
);

सरलीकृत कॉमनजेएस रैपर के साथ एक मॉड्यूल परिभाषित करें

यदि आप परंपरागत कॉमनजेएस मॉड्यूल प्रारूप में लिखे गए कुछ कोड का पुन: उपयोग करना चाहते हैं, तो उपरोक्त उपयोग की गई निर्भरताओं की सरणी पर फिर से काम करना मुश्किल हो सकता है, और आप निर्भरता नाम का प्रत्यक्ष संरेखण उस स्थानीय चर के लिए उपयोग कर सकते हैं निर्भरता। आप उन मामलों के लिए सरलीकृत कॉमनजेएस रैपर का उपयोग कर सकते हैं:

define(function(require, exports, module) {
        var a = require('a'),
            b = require('b');

        //Return the module value
        return function () {};
    }
);

यह रैपर फ़ंक्शन सामग्री का उपयोगी स्ट्रिंग मान देने के लिए Function.prototype.toString () पर निर्भर करता है। यह PS3 और कुछ पुराने ओपेरा मोबाइल ब्राउज़र जैसे कुछ उपकरणों पर काम नहीं करता है। उन उपकरणों पर उपयोग के लिए सरणी प्रारूप में निर्भरताओं को खींचने के लिए अनुकूलक का उपयोग करें।

अधिक जानकारी कॉमनजेएस पृष्ठ पर और क्यों एएमडी पृष्ठ में "चीनी" खंड में उपलब्ध है

एक नाम के साथ एक मॉड्यूल परिभाषित करें

आपको कुछ परिभाषित () कॉल का सामना करना पड़ सकता है जिसमें मॉड्यूल के लिए नाम परिभाषित करने के पहले तर्क के रूप में नाम शामिल है ():

    //Explicitly defines the "foo/title" module:
    define("foo/title",
        ["my/cart", "my/inventory"],
        function(cart, inventory) {
            //Define foo/title object in here.
       }
    );

ये आमतौर पर अनुकूलन उपकरण द्वारा उत्पन्न होते हैं। आप स्पष्ट रूप से मॉड्यूल का नाम दे सकते हैं, लेकिन यह मॉड्यूल को कम पोर्टेबल बनाता है - यदि आप फ़ाइल को दूसरी निर्देशिका में ले जाते हैं तो आपको नाम बदलना होगा। मॉड्यूल के नाम पर कोडिंग से बचने के लिए सामान्य रूप से सर्वोत्तम होता है और मॉड्यूल नामों में ऑप्टिमाइज़ेशन टूल को जला दें। अनुकूलन उपकरण को नाम जोड़ने की आवश्यकता है ताकि ब्राउज़र में तेज़ी से लोड होने की अनुमति देने के लिए फ़ाइल में एक से अधिक मॉड्यूल को बंडल किया जा सके।

अन्य मॉड्यूल नोट्स

प्रति फ़ाइल एक मॉड्यूल। : मॉड्यूल नाम-से-फ़ाइल-पथ लुकअप एल्गोरिदम की प्रकृति को देखते हुए, केवल एक मॉड्यूल प्रति जावास्क्रिप्ट फ़ाइल को परिभाषित किया जाना चाहिए। ऑप्टिमाइज्ड फ़ाइलों में एकाधिक मॉड्यूल को समूहित करने के लिए आप केवल ऑप्टिमाइज़ेशन टूल का उपयोग करते हैं।

परिभाषित करने के अंदर संबंधित मॉड्यूल नाम () : आवश्यकता के लिए ("./ सापेक्ष / नाम") कॉल जो परिभाषित () फ़ंक्शन कॉल के अंदर हो सकती है, निर्भरता के रूप में "आवश्यकता" मांगना सुनिश्चित करें, ताकि सापेक्ष नाम हल हो जाए सही ढंग से:

define(["require", "./relative/name"], function(require) {
    var mod = require("./relative/name");
});

या बेहतर अभी तक, संक्षिप्त वाक्यविन्यास का उपयोग करें जो सामान्यजेएस मॉड्यूल का अनुवाद करने के लिए उपयोग के लिए उपलब्ध है:

define(function(require) {
    var mod = require("./relative/name");
});

यह फॉर्म आवश्यकता () कॉल खोजने के लिए Function.prototype.toString () का उपयोग करेगा, और उन्हें "आवश्यकता" के साथ निर्भरता सरणी में जोड़ देगा, इसलिए कोड सापेक्ष पथों के साथ सही ढंग से काम करेगा।

सापेक्ष पथ वास्तव में उपयोगी होते हैं यदि आप निर्देशिका के अंदर कुछ मॉड्यूल बना रहे हैं, ताकि आप निर्देशिका को अन्य लोगों या अन्य परियोजनाओं के साथ साझा कर सकें, और आप उस निर्देशिका में भाई मॉड्यूल पर संभाल नहीं लेना चाहते हैं निर्देशिका का नाम पता है।

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

* lib/
    * compute/
        * main.js
        * extras.js

जहां main.js मॉड्यूल इस तरह दिखता है:

define(["./extras"], function(extras) {
    //Uses extras in here.
});

यदि यह पथ कॉन्फ़िगर था:

require.config({
    baseUrl: 'lib',
    paths: {
      'compute': 'compute/main'
    }
});

और एक require(['compute']) किया जाता है, तो lib / compute / main.js में 'गणना' का मॉड्यूल नाम होगा। जब यह './extras' के लिए पूछता है, जिसे 'गणना' के सापेक्ष हल किया जाता है, तो 'गणना / ./ अतिरिक्त', जो केवल 'अतिरिक्त' को सामान्यीकृत करता है। चूंकि उस मॉड्यूल नाम के लिए कोई पथ कॉन्फ़िगर नहीं है, इसलिए उत्पन्न पथ 'lib / extras.js' के लिए होगा, जो गलत है।

इस मामले के लिए, संकुल कॉन्फ़िगरेशन एक बेहतर विकल्प है, क्योंकि यह मुख्य मॉड्यूल को 'गणना' के रूप में सेट करने की अनुमति देता है, लेकिन आंतरिक रूप से लोडर मॉड्यूल को 'गणना / मुख्य' की आईडी के साथ संग्रहीत करेगा ताकि './ के सापेक्ष संदर्भ अतिरिक्त 'काम करता है।

एक और विकल्प lib / compute.js पर एक मॉड्यूल बनाना है जो केवल define(['./compute/main'], function(m) { return m; }); , तो पथ या संकुल विन्यास की कोई आवश्यकता नहीं है।

या, उस पथ या संकुल कॉन्फ़िगरेशन को सेट न करें और शीर्ष स्तर को आवश्यकता के अनुसार कॉल की require(['compute/main'])

मॉड्यूल से संबंधित यूआरएल उत्पन्न करें : आपको एक मॉड्यूल के सापेक्ष एक यूआरएल उत्पन्न करने की आवश्यकता हो सकती है। ऐसा करने के लिए, निर्भरता के रूप में "आवश्यकता" मांगें और फिर यूआरएल उत्पन्न करने के लिए requ.toUrl () का उपयोग करें:

define(["require"], function(require) {
    var cssUrl = require.toUrl("./style.css");
});

कंसोल डीबगिंग : यदि आपको किसी मॉड्यूल के साथ काम करने की आवश्यकता है जिसे आप पहले से ही एक require(["module/name"], function(){}) माध्यम से लोड किया गया है, तो जावास्क्रिप्ट कंसोल में कॉल करें, फिर आप आवश्यक () फॉर्म का उपयोग कर सकते हैं जो अभी उपयोग करता है इसे लाने के लिए मॉड्यूल का स्ट्रिंग नाम:

require("module/name").callSomeFunction()

ध्यान दें यह केवल तभी काम करता है जब "मॉड्यूल / नाम" पहले आवश्यकतानुसार एसिंक संस्करण के माध्यम से लोड किया गया था: require(["module/name"]) । यदि एक सापेक्ष पथ का उपयोग करना है, जैसे './module/name', तो वे केवल परिभाषित किए गए काम करते हैं

परिपत्र निर्भरता

यदि आप एक परिपत्र निर्भरता परिभाषित करते हैं ("ए" जरूरतों "बी" और "बी" की आवश्यकता "ए"), तो इस मामले में जब "बी" मॉड्यूल फ़ंक्शन कहा जाता है, तो उसे "ए" के लिए एक अनिर्धारित मान प्राप्त होगा। "बी" बाद में मॉड्यूल को आवश्यकता () विधि का उपयोग करके परिभाषित किया गया है (निर्भरता के रूप में आवश्यकता निर्दिष्ट करने के लिए सुनिश्चित करें ताकि सही संदर्भ का उपयोग "ए" को देखने के लिए किया जा सके):

//Inside b.js:
define(["require", "a"],
    function(require, a) {
        //"a" in this case will be null if "a" also asked for "b",
        //a circular dependency.
        return function(title) {
            return require("a").doSomething();
        }
    }
);

आम तौर पर आपको मॉड्यूल लाने के लिए आवश्यकता () का उपयोग करने की आवश्यकता नहीं है, बल्कि इसके बजाय फ़ंक्शन में एक तर्क के रूप में पारित मॉड्यूल पर भरोसा करना चाहिए। परिपत्र निर्भरता दुर्लभ होती है, और आमतौर पर एक संकेत है कि आप डिज़ाइन पर पुनर्विचार करना चाहेंगे। हालांकि, कभी-कभी उन्हें आवश्यकता होती है, और उस स्थिति में, ऊपर निर्दिष्ट अनुसार () की आवश्यकता होती है।

यदि आप कॉमनजेएस मॉड्यूल से परिचित हैं, तो आप मॉड्यूल के लिए खाली ऑब्जेक्ट बनाने के लिए निर्यात का उपयोग कर सकते हैं जो तुरंत अन्य मॉड्यूल के संदर्भ में उपलब्ध है। एक परिपत्र निर्भरता के दोनों किनारों पर ऐसा करके, आप सुरक्षित रूप से अन्य मॉड्यूल पर जा सकते हैं। यह केवल तभी काम करता है जब प्रत्येक मॉड्यूल मॉड्यूल मान के लिए ऑब्जेक्ट निर्यात कर रहा हो, फ़ंक्शन नहीं:

//Inside b.js:
define(function(require, exports, module) {
    //If "a" has used exports, then we have a real
    //object reference here. However, we cannot use
    //any of "a"'s properties until after "b" returns a value.
    var a = require("a");

    exports.foo = function () {
        return a.bar();
    };
});

या, यदि आप निर्भरता सरणी दृष्टिकोण का उपयोग कर रहे हैं, तो विशेष 'निर्यात' निर्भरता के लिए पूछें :

//Inside b.js:
define(['a', 'exports'], function(a, exports) {
    //If "a" has used exports, then we have a real
    //object reference here. However, we cannot use
    //any of "a"'s properties until after "b" returns a value.

    exports.foo = function () {
        return a.bar();
    };
});

एक JSONP सेवा निर्भरता निर्दिष्ट करें

JSONP जावास्क्रिप्ट में कुछ सेवाओं को कॉल करने का एक तरीका है। यह डोमेन पर काम करता है और यह उन सेवाओं को कॉल करने के लिए एक स्थापित दृष्टिकोण है जिन्हें केवल एक स्क्रिप्ट टैग के माध्यम से HTTP GET की आवश्यकता होती है।

RequJS में JSONP सेवा का उपयोग करने के लिए, कॉलबैक पैरामीटर के मान के रूप में "परिभाषित करें" निर्दिष्ट करें। इसका मतलब है कि आप एक JSONP यूआरएल का मान प्राप्त कर सकते हैं जैसे कि यह मॉड्यूल परिभाषा थी।

यहां एक उदाहरण दिया गया है जो JSONP API एंडपॉइंट को कॉल करता है। इस उदाहरण में, JSONP कॉलबैक पैरामीटर को "कॉलबैक" कहा जाता है, इसलिए "कॉलबैक = परिभाषित" एपीआई को "परिभाषित ()" रैपर में JSON प्रतिक्रिया को लपेटने के लिए कहता है:

require(["http://example.com/api/data.json?callback=define"],
    function (data) {
        //The data object will be the API response for the
        //JSONP data call.
        console.log(data);
    }
);

जेएसओएनपी का यह उपयोग प्रारंभिक एप्लिकेशन सेटअप के लिए जेएसओएनपी सेवाओं तक ही सीमित होना चाहिए। यदि JSONP सेवा का समय समाप्त हो जाता है, तो इसका मतलब है कि परिभाषित () के माध्यम से परिभाषित अन्य मॉड्यूल निष्पादित नहीं हो सकते हैं, इसलिए त्रुटि प्रबंधन मजबूत नहीं है।

केवल JSONP वापसी मान जो JSON ऑब्जेक्ट्स समर्थित हैं समर्थित हैं । एक JSONP प्रतिक्रिया जो एक सरणी है, एक स्ट्रिंग या संख्या काम नहीं करेगी।

इस कार्यक्षमता का उपयोग लंबे समय तक मतदान जेएसओएनपी कनेक्शन के लिए नहीं किया जाना चाहिए - एपीआई जो वास्तविक समय स्ट्रीमिंग से निपटती हैं। प्रत्येक प्रतिक्रिया प्राप्त करने के बाद उन प्रकार के एपीआई को अधिक स्क्रिप्ट क्लीनअप करना चाहिए, और RequJS केवल एक बार JSONP यूआरएल लाएगा - एक यूआरएल के बाद के उपयोगों को एक आवश्यकता () या परिभाषित () कॉल में निर्भरता के रूप में एक कैश वैल्यू मिलेगा।

एक JSONP सेवा लोड करने में त्रुटियां आम तौर पर सेवा के लिए टाइमआउट के माध्यम से सामने आती हैं, क्योंकि स्क्रिप्ट टैग लोडिंग नेटवर्क समस्याओं में अधिक जानकारी नहीं देती है। त्रुटियों का पता लगाने के लिए, आप त्रुटियों को प्राप्त करने के लिए requirejs.onError () को ओवरराइड कर सकते हैं। हैंडलिंग त्रुटियों अनुभाग में अधिक जानकारी है।

एक मॉड्यूल को परिभाषित करना

एक वैश्विक फ़ंक्शन है, requirejs.undef () , जो मॉड्यूल को अपरिभाषित करने की अनुमति देता है। मॉड्यूल की पिछली परिभाषा को भूलने के लिए यह लोडर की आंतरिक स्थिति को रीसेट करेगा।

हालांकि , यह मॉड्यूल को अन्य मॉड्यूल से नहीं हटाएगा जो पहले ही परिभाषित हैं और उस मॉड्यूल पर एक हैंडल प्राप्त करते हैं जब वे निष्पादित होते हैं। तो यह वास्तव में केवल त्रुटि स्थितियों में उपयोग करने के लिए उपयोगी है जब किसी अन्य मॉड्यूल को मॉड्यूल मान पर एक संभाल नहीं मिला है, या उस मॉड्यूल का उपयोग करने वाले भविष्य के मॉड्यूल लोडिंग के हिस्से के रूप में। उदाहरण के लिए त्रुटि खंड देखें।

यदि आप काम को अपरिभाषित करने के लिए अधिक परिष्कृत निर्भरता ग्राफ विश्लेषण करना चाहते हैं, तो अर्द्ध-निजी ऑन रिसोर्सलोड एपीआई सहायक हो सकती है।

यांत्रिकी

KeyJS head.appendChild () का उपयोग करके प्रत्येक निर्भरता को स्क्रिप्ट टैग के रूप में लोड करता है।

RequJS लोड करने के लिए सभी निर्भरताओं की प्रतीक्षा करता है, मॉड्यूल को परिभाषित करने वाले कार्यों को कॉल करने के लिए सही क्रम का आंकड़ा देता है, फिर उन कार्यों के लिए निर्भरता के बाद मॉड्यूल परिभाषा कार्यों को कॉल करता है। ध्यान दें कि दिए गए मॉड्यूल परिभाषा फ़ंक्शन के लिए निर्भरता किसी भी क्रम में उनके उप-निर्भरता संबंधों और नेटवर्क लोड ऑर्डर के कारण बुलाया जा सकता है।

एक सर्वर-साइड जावास्क्रिप्ट वातावरण में RequJS का उपयोग करना जिसमें सिंक्रोनस लोडिंग है, को पुनः लोड करना आवश्यक है .load ()। बिल्ड सिस्टम यह करता है, उस पर्यावरण के लिए require.load विधि बिल्ड / jslib / requirePatch.js में पाया जा सकता है।

भविष्य में, इस कोड को एक वैकल्पिक मॉड्यूल के रूप में आवश्यकता / निर्देशिका में खींचा जा सकता है जिसे आप मेजबान वातावरण के आधार पर सही लोड व्यवहार प्राप्त करने के लिए अपने env में लोड कर सकते हैं।

कॉन्फ़िगरेशन विकल्प

शीर्ष-स्तरीय HTML पृष्ठ (या शीर्ष-स्तरीय स्क्रिप्ट फ़ाइल जो मॉड्यूल को परिभाषित नहीं करता है) में आवश्यकता () का उपयोग करते समय, कॉन्फ़िगरेशन ऑब्जेक्ट को पहले विकल्प के रूप में पारित किया जा सकता है:

<script src="scripts/require.js"></script>
<script>
  require.config({
    baseUrl: "/another/path",
    paths: {
        "some": "some/v1.0"
    },
    waitSeconds: 15
  });
  require( ["some/module", "my/module", "a.js", "b.js"],
    function(someModule,    myModule) {
        //This function will be called when all the dependencies
        //listed above are loaded. Note that this function could
        //be called before the page is loaded.
        //This callback is optional.
    }
  );
</script>

आप अपने डेटा-मुख्य एंट्री प्वाइंट से requ.config को भी कॉल कर सकते हैं, लेकिन ध्यान रखें कि डेटा-मुख्य स्क्रिप्ट को असीमित रूप से लोड किया जाता है। अन्य प्रविष्टि बिंदु स्क्रिप्ट से बचें जो गलत तरीके से मानते हैं कि डेटा-मुख्य और इसकी आवश्यकताएँ .config हमेशा उनके स्क्रिप्ट लोडिंग से पहले निष्पादित होगा।

साथ ही, आप कॉन्फ़िगरेशन ऑब्जेक्ट को परिभाषित कर सकते हैं क्योंकि वैश्विक चर require .js लोड होने से पहले , और मान स्वचालित रूप से लागू होते हैं। यह उदाहरण आवश्यकता के अनुसार कुछ निर्भरताओं को लोड करने के लिए निर्दिष्ट करता है। जेएस परिभाषित करता है ():

<script>
    var require = {
        deps: ["some/module1", "my/module2", "a.js", "b.js"],
        callback: function(module1, module2) {
            //This function will be called when all the dependencies
            //listed above in deps are loaded. Note that this
            //function could be called before the page is loaded.
            //This callback is optional.
        }
    };
</script>
<script src="scripts/require.js"></script>

नोट: var require = {} का उपयोग करना सबसे अच्छा है और window.require = {} उपयोग न करें, यह IE में सही ढंग से व्यवहार नहीं करेगा।

कॉन्फ़िगरेशन को मुख्य मॉड्यूल लोडिंग से अलग करने के लिए कुछ पैटर्न हैं।

समर्थित विन्यास विकल्प:

baseUrl : सभी मॉड्यूल लुकअप के लिए उपयोग करने के लिए रूट पथ। तो उपर्युक्त उदाहरण में, "मेरे / मॉड्यूल" के स्क्रिप्ट टैग में एक src = "/ else / path / my / module.js" होगा। baseUrl का उपयोग सादा .js फ़ाइलों को लोड करते समय नहीं किया जाता है ( स्लैश से शुरू होने वाली निर्भरता स्ट्रिंग द्वारा इंगित किया गया है , प्रोटोकॉल है, या .js में समाप्त होता है ), उन तारों का उपयोग इस प्रकार किया जाता है, इसलिए a.js और b.js होंगे एचटीएमएल पेज के समान निर्देशिका से लोड किया गया जिसमें उपरोक्त स्निपेट है।

यदि कोई baseUrl कॉन्फ़िगरेशन में स्पष्ट रूप से सेट नहीं है, तो डिफ़ॉल्ट मान HTML पृष्ठ का स्थान होगा जो requ.js लोड करता है। यदि डेटा-मुख्य विशेषता का उपयोग किया जाता है, तो वह पथ baseUrl बन जाएगा।

BaseUrl एक अलग डोमेन पर एक यूआरएल हो सकता है जो पृष्ठ को requ.js लोड करेगा। RequJS स्क्रिप्ट लोडिंग डोमेन पर काम करता है। टेक्स्ट द्वारा लोड की गई टेक्स्ट सामग्री पर एकमात्र प्रतिबंध है! प्लगइन्स: कम से कम विकास के दौरान उन पथों को पृष्ठ के समान डोमेन पर होना चाहिए। ऑप्टिमाइज़ेशन टूल टेक्स्ट इनलाइन करेगा! प्लगइन संसाधन ऑप्टिमाइज़ेशन टूल का उपयोग करने के बाद, आप टेक्स्ट का संदर्भ देने वाले संसाधनों का उपयोग कर सकते हैं! किसी अन्य डोमेन से प्लगइन संसाधन।

पथ : मॉड्यूल नामों के लिए पथ मैपिंग सीधे आधार यूआरएल के तहत नहीं मिलते हैं। पथ सेटिंग्स को बेसयूआरएल के सापेक्ष माना जाता है, जब तक कि पथ सेटिंग "/" से शुरू न हो या इसमें कोई URL प्रोटोकॉल न हो ("http:")। उपर्युक्त नमूना विन्यास का उपयोग करके, "कुछ / मॉड्यूल" का स्क्रिप्ट टैग src = "/ another / path / some / v1.0 / module.js" होगा।

मॉड्यूल नाम के लिए उपयोग किया जाने वाला पथ में एक्सटेंशन शामिल नहीं होना चाहिए, क्योंकि पथ मैपिंग निर्देशिका के लिए हो सकती है। पथ मैपिंग कोड पथ पर मॉड्यूल नाम मैप करते समय .js एक्सटेंशन स्वचालित रूप से जोड़ देगा। यदि require.toUrl() का उपयोग किया जाता है, तो यह उचित एक्सटेंशन जोड़ देगा, अगर यह किसी टेक्स्ट टेम्पलेट की तरह है।

जब ब्राउज़र में चलाया जाता है, तो सीडीएन स्थान से लोड करने की अनुमति देने के लिए पथ फ़ॉलबैक निर्दिष्ट किए जा सकते हैं, लेकिन यदि सीडीएन स्थान लोड होने में विफल रहता है तो स्थानीय स्थान पर वापस आना।

bundles : RequJS 2.1.10 में प्रस्तुत किया गया: एकाधिक मॉड्यूल आईडी को किसी अन्य स्क्रिप्ट में कॉन्फ़िगर करने की अनुमति देता है। उदाहरण:

requirejs.config({
    bundles: {
        'primary': ['main', 'util', 'text', 'text!template.html'],
        'secondary': ['text!secondary.html']
    }
});

require(['util', 'text'], function(util, text) {
    //The script for module ID 'primary' was loaded,
    //and that script included the define()'d
    //modules for 'util' and 'text'
});

उस कॉन्फ़िगरेशन में कहा गया है: मॉड्यूल 'मुख्य', 'उपयोग', 'टेक्स्ट' और 'टेक्स्ट! Template.html' मॉड्यूल आईडी 'प्राथमिक' लोड करके पाए जाएंगे। मॉड्यूल 'टेक्स्ट! माध्यमिक.html' मॉड्यूल आईडी 'माध्यमिक' लोड करके पाया जा सकता है।

यह केवल एक स्क्रिप्ट के अंदर एक मॉड्यूल खोजने के लिए सेट करता है जिसमें एकाधिक परिभाषित () 'डी मॉड्यूल हैं। यह स्वचालित रूप से उन मॉड्यूल को बंडल के मॉड्यूल आईडी में बाध्य नहीं करता है। बंडल की मॉड्यूल आईडी का उपयोग मॉड्यूल के सेट को ढूंढने के लिए किया जाता है।

पथ कॉन्फ़िगरेशन के साथ कुछ समान संभव है, लेकिन यह बहुत शब्दशः है, और पथ कॉन्फ़िगर रूट लोडर प्लगइन संसाधन आईडी को इसकी कॉन्फ़िगरेशन में अनुमति नहीं देता है, क्योंकि पथ कॉन्फ़िगरेशन मान पथ खंड हैं, आईडी नहीं।

बंडल कॉन्फ़िगरेशन उपयोगी है अगर कोई बिल्ड करना और लक्ष्य बनाना मौजूदा मॉड्यूल आईडी नहीं था, या यदि आपके पास जेएस फाइलों में लोडर प्लगइन संसाधन हैं जो लोडर प्लगइन द्वारा लोड नहीं किए जाने चाहिए। ध्यान दें कि कुंजी और मान मॉड्यूल आईडी हैं , पथ खंड नहीं। वे पूर्ण मॉड्यूल आईडी हैं, न कि मॉड्यूल आईडी उपसर्ग जैसे पथ कॉन्फ़िगर या मैप कॉन्फ़िगरेशन । साथ ही, बंडल कॉन्फ़िगरेशन मानचित्र कॉन्फ़िगरेशन से अलग है, उस मानचित्र कॉन्फ़िगरेशन में एक-से-एक मॉड्यूल आईडी संबंध है, जहां बंडल कॉन्फ़िगरेशन एक बंडल के मॉड्यूल आईडी पर एकाधिक मॉड्यूल आईडी को इंगित करने के लिए है।

RequJS 2.2.0 के रूप में, ऑप्टिमाइज़र बंडल कॉन्फ़िगरेशन उत्पन्न कर सकता है और उसे शीर्ष स्तर requjs.config () कॉल में डाल सकता है। अधिक जानकारी के लिए bundlesConfigOutFile बिल्ड कॉन्फ़िगरेशन विकल्प देखें।

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

यहाँ एक उदाहरण है। इसके लिए RequJS 2.1.0+ की आवश्यकता है, और backbone.js मानता है, underscore.js और jquery.js baseUrl निर्देशिका में स्थापित किए गए हैं। यदि नहीं, तो आपको उनके लिए पथ कॉन्फ़िगरेशन सेट करने की आवश्यकता हो सकती है:

requirejs.config({
    //Remember: only use shim config for non-AMD scripts,
    //scripts that do not already call define(). The shim
    //config will not work correctly if used on AMD scripts,
    //in particular, the exports and init config will not
    //be triggered, and the deps config will be confusing
    //for those cases.
    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.
                //Note: jQuery registers as an AMD module via define(),
                //so this will not work for jQuery. See notes section
                //below for an approach for jQuery.
                return this.Foo.noConflict();
            }
        }
    }
});

//Then, later in a separate file, call it 'MyModel.js', a module is
//defined, specifying 'backbone' as a dependency. RequireJS will use
//the shim config to properly load 'backbone' and give a local
//reference to this module. The global Backbone will still exist on
//the page too.
define(['backbone'], function (Backbone) {
  return Backbone.Model.extend({});
});

RequJS 2.0 में। *, Shim config में "निर्यात" प्रॉपर्टी स्ट्रिंग के बजाय फ़ंक्शन हो सकती थी। उस स्थिति में, यह ऊपर दिखाए गए अनुसार "init" संपत्ति के समान कार्य करता है। "Init" पैटर्न को RequJS 2.1.0+ में उपयोग किया जाता है, इसलिए exports लिए एक स्ट्रिंग मान का उपयोग enforceDefine लिए किया जा सकता है, लेकिन लाइब्रेरी लोड होने के बाद ज्ञात कार्य करने की अनुमति देता है।

"मॉड्यूल" के लिए जो सिर्फ jQuery या बैकबोन प्लगइन्स हैं जिन्हें किसी भी मॉड्यूल मान को निर्यात करने की आवश्यकता नहीं है, शिम कॉन्फ़िगरेशन केवल निर्भरताओं की एक सरणी हो सकती है:

requirejs.config({
    shim: {
        'jquery.colorize': ['jquery'],
        'jquery.scroll': ['jquery'],
        'backbone.layoutmanager': ['backbone']
    }
});

नोट हालांकि यदि आप आईई में 404 लोड डिटेक्शन प्राप्त करना चाहते हैं ताकि आप पथ फॉलबैक या इरबैक का उपयोग कर सकें, तो एक स्ट्रिंग निर्यात मान दिया जाना चाहिए ताकि लोडर वास्तव में स्क्रिप्ट लोड कर सके या नहीं ( enforceDefine से वापसी का उपयोग लागू करने के लिए नहीं किया जाता है जाँच):

requirejs.config({
    shim: {
        'jquery.colorize': {
            deps: ['jquery'],
            exports: 'jQuery.fn.colorize'
        },
        'jquery.scroll': {
            deps: ['jquery'],
            exports: 'jQuery.fn.scroll'
        },
        'backbone.layoutmanager': {
            deps: ['backbone']
            exports: 'Backbone.LayoutManager'
        }
    }
});

"शिम" कॉन्फ़िगरेशन के लिए महत्वपूर्ण नोट्स:

  • शिम कॉन्फ़िगरेशन केवल कोड संबंध स्थापित करता है। मॉड्यूल लोड करने के लिए जो कि शिम कॉन्फ़िगरेशन का हिस्सा हैं या उपयोग करते हैं, सामान्य आवश्यकता / परिभाषित कॉल की आवश्यकता होती है। अपने आप से शिम सेट करना लोड करने के लिए कोड ट्रिगर नहीं करता है।
  • केवल "शिम" मॉड्यूल का उपयोग शिमयुक्त स्क्रिप्ट्स, या एएमडी पुस्तकालयों के लिए निर्भरता के रूप में करें, जिन पर कोई निर्भरता नहीं है और परिभाषित () को ग्लोबल (जैसे jQuery या लॉनाश) बनाने के बाद कॉल करें। अन्यथा, यदि आप एक निर्माण के बाद एक एएमडी मॉड्यूल को एक शिम कॉन्फ़िगरेशन मॉड्यूल के लिए निर्भरता के रूप में उपयोग करते हैं, तो निर्माण निष्पादन में shimmed कोड के बाद तक AMD मॉड्यूल का मूल्यांकन नहीं किया जा सकता है, और एक त्रुटि उत्पन्न होगी। अंतिम फिक्स वैकल्पिक shdmed कोड को वैकल्पिक एएमडी परिभाषित () कॉल करने के लिए अपग्रेड करना है।
  • यदि एएमडी परिभाषित () कॉल का उपयोग करने के लिए shimmed कोड को अपग्रेड करना संभव नहीं है, तो RequJS 2.1.11 के रूप में, ऑप्टिमाइज़र में एक wrapShim build विकल्प है जो एक निर्माण के लिए स्वचालित रूप से shimmed कोड को लपेटने का प्रयास करेगा। यह shimmed निर्भरताओं के दायरे को बदलता है, इसलिए यह हमेशा काम करने की गारंटी नहीं है, लेकिन, उदाहरण के लिए, शेम्ड निर्भरताओं के लिए जो बैकबोन के एएमडी संस्करण पर निर्भर करता है, यह सहायक हो सकता है।
  • एएमडी मॉड्यूल के लिए इनिट फ़ंक्शन नहीं कहा जाएगा। उदाहरण के लिए, आप jQuery के नो कॉन्फ्लिक्ट को कॉल करने के लिए शिम इनिट फ़ंक्शन का उपयोग नहीं कर सकते हैं। JQuery के वैकल्पिक दृष्टिकोण के लिए NoConflict का उपयोग करने के लिए मैपिंग मॉड्यूल देखें।
  • RequJS के माध्यम से नोड में एएमडी मॉड्यूल चलाते समय शिम कॉन्फ़िगरेशन समर्थित नहीं है (हालांकि यह ऑप्टिमाइज़र उपयोग के लिए काम करता है)। मॉड्यूल को घुमाया जा रहा है, यह नोड में विफल हो सकता है क्योंकि नोड में ब्राउज़र के समान वैश्विक वातावरण नहीं है। RequJS 2.1.7 के रूप में, यह आपको कंसोल में चेतावनी देगा कि शिम कॉन्फ़िगरेशन समर्थित नहीं है, और यह काम कर सकता है या नहीं भी। If you wish to suppress that message, you can pass requirejs.config({ suppress: { nodeShim: true }});

Important optimizer notes for "shim" config :

  • You should use the mainConfigFile build option to specify the file where to find the shim config. Otherwise the optimizer will not know of the shim config. The other option is to duplicate the shim config in the build profile.
  • Do not mix CDN loading with shim config in a build. Example scenario: you load jQuery from the CDN but use the shim config to load something like the stock version of Backbone that depends on jQuery. When you do the build, be sure to inline jQuery in the built file and do not load it from the CDN. Otherwise, Backbone will be inlined in the built file and it will execute before the CDN-loaded jQuery will load. This is because the shim config just delays loading of the files until dependencies are loaded, but does not do any auto-wrapping of define. After a build, the dependencies are already inlined, the shim config cannot delay execution of the non-define()'d code until later. define()'d modules do work with CDN loaded code after a build because they properly wrap their source in define factory function that will not execute until dependencies are loaded. So the lesson: shim config is a stop-gap measure for non-modular code, legacy code. define()'d modules are better.
  • For local, multi-file builds, the above CDN advice also applies. For any shimmed script, its dependencies must be loaded before the shimmed script executes. This means either building its dependencies directly in the buid layer that includes the shimmed script, or loading its dependencies with a require([], function (){}) call, then doing a nested require([]) call for the build layer that has the shimmed script.
  • If you are using uglifyjs to minify the code, do not set the uglify option toplevel to true, or if using the command line do not pass -mt . That option mangles the global names that shim uses to find exports.

map : For the given module prefix, instead of loading the module with the given ID, substitute a different module ID.

This sort of capability is really important for larger projects which may have two sets of modules that need to use two different versions of 'foo', but they still need to cooperate with each other.

This is not possible with the context-backed multiversion support . In addition, the paths config is only for setting up root paths for module IDs, not for mapping one module ID to another one.

map example:

requirejs.config({
    map: {
        'some/newmodule': {
            'foo': 'foo1.2'
        },
        'some/oldmodule': {
            'foo': 'foo1.0'
        }
    }
});

If the modules are laid out on disk like this:

  • foo1.0.js
  • foo1.2.js
  • some/
    • newmodule.js
    • oldmodule.js

When 'some/newmodule' does `require('foo')` it will get the foo1.2.js file, and when 'some/oldmodule' does `require('foo')` it will get the foo1.0.js file.

This feature only works well for scripts that are real AMD modules that call define() and register as anonymous modules. Also, only use absolute module IDs for map config. Relative IDs (like '../some/thing' ) do not work.

There is also support for a "*" map value which means "for all modules loaded, use this map config". If there is a more specific map config, that one will take precedence over the star config. उदाहरण:

requirejs.config({
    map: {
        '*': {
            'foo': 'foo1.2'
        },
        'some/oldmodule': {
            'foo': 'foo1.0'
        }
    }
});

Means that for any module except "some/oldmodule", when "foo" is wanted, use "foo1.2" instead. For "some/oldmodule" only, use "foo1.0" when it asks for "foo".

Note: when doing builds with map config, the map config needs to be fed to the optimizer, and the build output must still contain a requirejs config call that sets up the map config. The optimizer does not do ID renaming during the build, because some dependency references in a project could depend on runtime variable state. So the optimizer does not invalidate the need for a map config after the build.

config : There is a common need to pass configuration info to a module. That configuration info is usually known as part of the application, and there needs to be a way to pass that down to a module. In RequireJS, that is done with the config option for requirejs.config(). Modules can then read that info by asking for the special dependency "module" and calling module.config() . उदाहरण:

requirejs.config({
    config: {
        'bar': {
            size: 'large'
        },
        'baz': {
            color: 'blue'
        }
    }
});

//bar.js, which uses simplified CJS wrapping:
//http://requirejs.org/docs/whyamd.html#sugar
define(function (require, exports, module) {
    //Will be the value 'large'
    var size = module.config().size;
});

//baz.js which uses a dependency array,
//it asks for the special module ID, 'module':
//https://github.com/requirejs/requirejs/wiki/Differences-between-the-simplified-CommonJS-wrapper-and-standard-AMD-define#wiki-magic
define(['module'], function (module) {
    //Will be the value 'blue'
    var color = module.config().color;
});

For passing config to a package , target the main module in the package, not the package ID:

requirejs.config({
    //Pass an API key for use in the pixie package's
    //main module.
    config: {
        'pixie/index': {
            apiKey: 'XJKDLNS'
        }
    },
    //Set up config for the "pixie" package, whose main
    //module is the index.js file in the pixie folder.
    packages: [
        {
            name: 'pixie',
            main: 'index'
        }
    ]
});

packages : configures loading modules from CommonJS packages. See the packages topic for more information.

nodeIdCompat : Node treats module ID example.js and example the same. By default these are two different IDs in RequireJS. If you end up using modules installed from npm, then you may need to set this config value to true to avoid resolution issues. This option only applies to treating the ".js" suffix differently, it does not do any other node resolution and evaluation matching such as .json file handling (JSON handling needs a 'json!' loader plugin anyway). Available in 2.1.10 and greater.

waitSeconds : The number of seconds to wait before giving up on loading a script. Setting it to 0 disables the timeout. The default is 7 seconds.

context : A name to give to a loading context. This allows require.js to load multiple versions of modules in a page, as long as each top-level require call specifies a unique context string. To use it correctly, see the Multiversion Support section.

deps : An array of dependencies to load. Useful when require is defined as a config object before require.js is loaded, and you want to specify dependencies to load as soon as require() is defined. Using deps is just like doing a require([]) call, but done as soon as the loader has processed the configuration. It does not block any other require() calls from starting their requests for modules, it is just a way to specify some modules to load asynchronously as part of a config block.

callback : A function to execute after deps have been loaded. Useful when require is defined as a config object before require.js is loaded, and you want to specify a function to require after the configuration's deps array has been loaded.

enforceDefine : If set to true, an error will be thrown if a script loads that does not call define() or have a shim exports string value that can be checked. See Catching load failures in IE for more information.

xhtml : If set to true, document.createElementNS() will be used to create script elements.

urlArgs : Extra query string arguments appended to URLs that RequireJS uses to fetch resources. Most useful to cache bust when the browser or server is not configured correctly. Example cache bust setting for urlArgs:

urlArgs: "bust=" +  (new Date()).getTime()

As of RequireJS 2.2.0, urlArgs can be a function. If a function, it will receive the module ID and the URL as parameters, and it should return a string that will be added to the end of the URL. Return an empty string if no args. Be sure to take care of adding the '?' or '&' depending on the existing state of the URL. उदाहरण:

requirejs.config({
    urlArgs: function(id, url) {
        var args = 'v=1';
        if (url.indexOf('view.html') !== -1) {
            args = 'v=2'
        }

        return (url.indexOf('?') === -1 ? '?' : '&') + args;
    }
});

During development it can be useful to use this, however be sure to remove it before deploying your code.

scriptType : Specify the value for the type="" attribute used for script tags inserted into the document by RequireJS. Default is "text/javascript". To use Firefox's JavaScript 1.8 features, use "text/javascript;version=1.8".

skipDataMain : Introduced in RequireJS 2.1.9: If set to true , skips the data-main attribute scanning done to start module loading. Useful if RequireJS is embedded in a utility library that may interact with other RequireJS library on the page, and the embedded version should not do data-main loading.

उन्नत उपयोग

Loading Modules from Packages

RequireJS supports loading modules that are in a CommonJS Packages directory structure, but some additional configuration needs to be specified for it to work. Specifically, there is support for the following CommonJS Packages features:

  • A package can be associated with a module name/prefix.
  • The package config can specify the following properties for a specific package:
    • name : The name of the package (used for the module name/prefix mapping)
    • location : The location on disk. Locations are relative to the baseUrl configuration value, unless they contain a protocol or start with a front slash (/).
    • main : The name of the module inside the package that should be used when someone does a require for "packageName". The default value is "main", so only specify it if it differs from the default. The value is relative to the package folder.

IMPORTANT NOTES

  • While the packages can have the CommonJS directory layout, the modules themselves should be in a module format that RequireJS can understand. Exception to the rule: if you are using the r.js Node adapter, the modules can be in the traditional CommonJS module format. You can use the CommonJS converter tool if you need to convert traditional CommonJS modules into the async module format that RequireJS uses.
  • Only one version of a package can be used in a project context at a time. You can use RequireJS multiversion support to load two different module contexts, but if you want to use Package A and B in one context and they depend on different versions of Package C, then that will be a problem. This may change in the future.

If you use a similar project layout as specified in the Start Guide , the start of your web project would look something like this (Node/Rhino-based projects are similar, just use the contents of the scripts directory as the top-level project directory):

  • project-directory/
    • project.html
    • scripts/
      • require.js

Here is how the example directory layout looks with two packages, cart and store :

  • project-directory/
    • project.html
    • scripts/
      • cart/
        • main.js
      • store/
        • main.js
        • util.js
      • main.js
      • require.js

project.html will have a script tag like this:

<script data-main="scripts/main" src="scripts/require.js"></script>

This will instruct require.js to load scripts/main.js. main.js uses the "packages" config to set up packages that are relative to require.js, which in this case are the source packages "cart" and "store":

//main.js contents
//Pass a config object to require
require.config({
    "packages": ["cart", "store"]
});

require(["cart", "store", "store/util"],
function (cart,   store,   util) {
    //use the modules as usual.
});

A require of "cart" means that it will be loaded from scripts/cart/main.js , since "main" is the default main module setting supported by RequireJS. A require of "store/util" will be loaded from scripts/store/util.js .

If the "store" package did not follow the "main.js" convention, and looked more like this:

  • project-directory/
    • project.html
    • scripts/
      • cart/
        • main.js
      • store/
        • store.js
        • util.js
      • main.js
      • package.json
      • require.js

Then the RequireJS configuration would look like so:

require.config({
    packages: [
        "cart",
        {
            name: "store",
            main: "store"
        }
    ]
});

To avoid verbosity, it is strongly suggested to always use packages that use "main" convention in their structure.

Multiversion Support

As mentioned in Configuration Options , multiple versions of a module can be loaded in a page by using different "context" configuration options. require.config() returns a require function that will use the context configuration. Here is an example that loads two different versions of the alpha and beta modules (this example is taken from one of the test files):

<script src="../require.js"></script>
<script>
var reqOne = require.config({
  context: "version1",
  baseUrl: "version1"
});

reqOne(["require", "alpha", "beta",],
function(require,   alpha,   beta) {
  log("alpha version is: " + alpha.version); //prints 1
  log("beta version is: " + beta.version); //prints 1

  setTimeout(function() {
    require(["omega"],
      function(omega) {
        log("version1 omega loaded with version: " +
             omega.version); //prints 1
      }
    );
  }, 100);
});

var reqTwo = require.config({
      context: "version2",
      baseUrl: "version2"
    });

reqTwo(["require", "alpha", "beta"],
function(require,   alpha,   beta) {
  log("alpha version is: " + alpha.version); //prints 2
  log("beta version is: " + beta.version); //prints 2

  setTimeout(function() {
    require(["omega"],
      function(omega) {
        log("version2 omega loaded with version: " +
            omega.version); //prints 2
      }
    );
  }, 100);
});
</script>

Note that "require" is specified as a dependency for the module. This allows the require() function that is passed to the function callback to use the right context to load the modules correctly for multiversion support. If "require" is not specified as a dependency, then there will likely be an error.

Loading Code After Page Load

The example above in the Multiversion Support section shows how code can later be loaded by nested require() calls.

Web Worker Support

As of release 0.12, RequireJS can be run inside a Web Worker. Just use importScripts() inside a web worker to load require.js (or the JS file that contains the require() definition), then call require.

You will likely need to set the baseUrl configuration option to make sure require() can find the scripts to load.

You can see an example of its use by looking at one of the files used in the unit test .

Rhino Support

RequireJS can be used in Rhino via the r.js adapter . See the r.js README for more information.

Nashorn Support

As of RequireJS 2.1.16, RequireJS can be used in Nashorn , Java 8+'s JavaScript engine, via the r.js adapter . See the r.js README for more information.

Handling Errors

The general class of errors are 404s for scripts (not found), network timeouts or errors in the scripts that are loaded. RequireJS has a few tools to deal with them: require-specific errbacks, a "paths" array config, and a global requirejs.onError.

The error object passed to errbacks and the global requirejs.onError function will usually contain two custom properties:

  • requireType : A string value with a general classification, like "timeout", "nodefine", "scripterror".
  • requireModules : an array of module names/URLs that timed out.

If you get an error with a requireModules, it probably means other modules that depend on the modules in that requireModules array are not defined.

Catching load failures in IE

Internet Explorer has a set of problems that make it difficult to detect load failures for errbacks/paths fallbacks:

  • script.onerror does not work in IE 6-8. There is no way to know if loading a script generates a 404, worse, it triggers the onreadystatechange with a complete state even in a 404 case.
  • script.onerror does work in IE 9+, but it has a bug where it does not fire script.onload event handlers right after execution of script, so it cannot support the standard method of allowing anonymous AMD modules. So script.onreadystatechange is still used. However, onreadystatechange fires with a complete state before the script.onerror function fires.

So it is very difficult with IE to allow both anonymous AMD modules, which are a core benefit of AMD modules, and reliable detect errors.

However, if you are in a project that you know uses define() to declare all of its modules, or it uses the shim config to specify string exports for anything that does not use define(), then if you set the enforceDefine config value to true, the loader can confirm if a script load by checking for the define() call or the existence of the shim's exports global value.

So if you want to support Internet Explorer, catch load errors, and have modular code either through direct define() calls or shim config, always set enforceDefine to be true. See the next section for an example.

NOTE : If you do set enforceDefine: true, and you use data-main="" to load your main JS module, then that main JS module must call define() instead of require() to load the code it needs. The main JS module can still call require/requirejs to set config values, but for loading modules it should use define().

If you then also use almond to build your code without require.js, be sure to use the insertRequire build setting to insert a require call for the main module -- that serves the same purpose of the initial require() call that data-main does.

require([]) errbacks

Errbacks, when used with requirejs.undef() , will allow you to detect if a module fails to load, undefine that module, reset the config to a another location, then try again.

A common use case for this is to use a CDN-hosted version of a library, but if that fails, switch to loading the file locally:

requirejs.config({
    enforceDefine: true,
    paths: {
        jquery: 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min'
    }
});

//Later
require(['jquery'], function ($) {
    //Do something with $ here
}, function (err) {
    //The errback, error callback
    //The error has a list of modules that failed
    var failedId = err.requireModules && err.requireModules[0];
    if (failedId === 'jquery') {
        //undef is function only on the global requirejs object.
        //Use it to clear internal knowledge of jQuery. Any modules
        //that were dependent on jQuery and in the middle of loading
        //will not be loaded yet, they will wait until a valid jQuery
        //does load.
        requirejs.undef(failedId);

        //Set the path to jQuery to local path
        requirejs.config({
            paths: {
                jquery: 'local/jquery'
            }
        });

        //Try again. Note that the above require callback
        //with the "Do something with $ here" comment will
        //be called if this new attempt to load jQuery succeeds.
        require(['jquery'], function () {});
    } else {
        //Some other error. Maybe show message to the user.
    }
});

With `requirejs.undef()`, if you later set up a different config and try to load the same module, the loader will still remember which modules needed that dependency and finish loading them when the newly configured module loads.

Note : errbacks only work with callback-style require calls, not define() calls. define() is only for declaring modules.

paths config fallbacks

The above pattern for detecting a load failure, undef()ing a module, modifying paths and reloading is a common enough request that there is also a shorthand for it. The paths config allows array values:

requirejs.config({
    //To get timely, correct error triggers in IE, force a define/shim exports check.
    enforceDefine: true,
    paths: {
        jquery: [
            'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min',
            //If the CDN location fails, load from this location
            'lib/jquery'
        ]
    }
});

//Later
require(['jquery'], function ($) {
});

This above code will try the CDN location, but if that fails, fall back to the local lib/jquery.js location.

Note : paths fallbacks only work for exact module ID matches. This is different from normal paths config which can apply to any part of a module ID prefix segment. Fallbacks are targeted more for unusual error recovery, not a generic path search path solution, since those are inefficient in the browser.

Global requirejs.onError function

To detect errors that are not caught by local errbacks, you can override requirejs.onError():

requirejs.onError = function (err) {
    console.log(err.requireType);
    if (err.requireType === 'timeout') {
        console.log('modules: ' + err.requireModules);
    }

    throw err;
};

Loader Plugins

RequireJS supports loader plugins . This is a way to support dependencies that are not plain JS files, but are still important for a script to have loaded before it can do its work. The RequireJS wiki has a list of plugins . This section talks about some specific plugins that are maintained alongside RequireJS:

Specify a Text File Dependency

It is nice to build HTML using regular HTML tags, instead of building up DOM structures in script. However, there is no good way to embed HTML in a JavaScript file. The best that can be done is using a string of HTML, but that can be hard to manage, particularly for multi-line HTML.

RequireJS has a plugin, text.js, that can help with this issue. It will automatically be loaded if the text! prefix is used for a dependency. See the text.js README for more information.

Page Load Event Support/DOM Ready

It is possible when using RequireJS to load scripts quickly enough that they complete before the DOM is ready. Any work that tries to interact with the DOM should wait for the DOM to be ready. For modern browsers, this is done by waiting for the DOMContentLoaded event.

However, not all browsers in use support DOMContentLoaded. The domReady module implements a cross-browser method to determine when the DOM is ready. Download the module and use it in your project like so:

require(['domReady'], function (domReady) {
  domReady(function () {
    //This function is called once the DOM is ready.
    //It will be safe to query the DOM and manipulate
    //DOM nodes in this function.
  });
});

चूंकि डीओएम तैयार एक आम अनुप्रयोग की आवश्यकता है, आदर्श रूप से ऊपर दिए गए एपीआई में नेस्टेड फ़ंक्शंस से बचा जा सकता है। DomReady मॉड्यूल भी लागू करता लोडर प्लगइन एपीआई , तो आप लोडर प्लगइन सिंटैक्स का उपयोग कर सकते हैं (नोटिस ! DomReady निर्भरता में) प्रतीक्षा करने के लिए आवश्यकता होती है () कॉलबैक समारोह के लिए मजबूर करने के लिए डोम को क्रियान्वित करने से पहले तैयार किया जाना है।

domReady
लोडर प्लगइन के रूप में उपयोग किए जाने पर वर्तमान दस्तावेज़ वापस कर देगा:
require(['domReady!'], function (doc) {
    //This function is called once the DOM is ready,
    //notice the value for 'domReady!' is the current
    //document.
});

Note: If the document takes a while to load (maybe it is a very large document, or has HTML script tags loading large JS files that block DOM completion until they are done), using domReady as a loader plugin may result in a RequireJS "timeout" error. If this is a problem either increase the waitSeconds configuration, or just use domReady as a module and call domReady() inside the require() callback.

Define an I18N Bundle

Once your web app gets to a certain size and popularity, localizing the strings in the interface and providing other locale-specific information becomes more useful. However, it can be cumbersome to work out a scheme that scales well for supporting multiple locales.

RequireJS allows you to set up a basic module that has localized information without forcing you to provide all locale-specific information up front. It can be added over time, and only strings/values that change between locales can be defined in the locale-specific file.

i18n bundle support is provided by the i18n.js plugin. It is automatically loaded when a module or dependency specifies the i18n! prefix (more info below). Download the plugin and put it in the same directory as your app's main JS file.

To define a bundle, put it in a directory called "nls" -- the i18n! plugin assumes a module name with "nls" in it indicates an i18n bundle. The "nls" marker in the name tells the i18n plugin where to expect the locale directories (they should be immediate children of the nls directory). If you wanted to provide a bundle of color names in your "my" set of modules, create the directory structure like so:

  • my/nls/colors.js

The contents of that file should look like so:

//my/nls/colors.js contents:
define({
    "root": {
        "red": "red",
        "blue": "blue",
        "green": "green"
    }
});

An object literal with a property of "root" defines this module. That is all you have to do to set the stage for later localization work.

You can then use the above module in another module, say, in a my/lamps.js file:

//Contents of my/lamps.js
define(["i18n!my/nls/colors"], function(colors) {
    return {
        testMessage: "The name for red in this locale is: " + colors.red
    }
});

The my/lamps module has one property called "testMessage" that uses colors.red to show the localized value for the color red.

Later, when you want to add a specific translation to a file, say for the fr-fr locale, change my/nls/colors to look like so:

//Contents of my/nls/colors.js
define({
    "root": {
        "red": "red",
        "blue": "blue",
        "green": "green"
    },
    "fr-fr": true
});

Then define a file at my/nls/fr-fr/colors.js that has the following contents:

//Contents of my/nls/fr-fr/colors.js
define({
    "red": "rouge",
    "blue": "bleu",
    "green": "vert"
});

RequireJS will use the browser's navigator.languages, navigator.language or navigator.userLanguage property to determine what locale values to use for my/nls/colors, so your app does not have to change. If you prefer to set the locale, you can use the config to pass the locale to the plugin:

requirejs.config({
    config: {
        //Set the config for the i18n
        //module ID
        i18n: {
            locale: 'fr-fr'
        }
    }
});

Note that RequireJS will always use a lowercase version of the locale, to avoid case issues, so all of the directories and files on disk for i18n bundles should use lowercase locales.

RequireJS is also smart enough to pick the right locale bundle, the one that most closely matches the ones provided by my/nls/colors. For instance, if the locale is "en-us", then the "root" bundle will be used. If the locale is "fr-fr-paris" then the "fr-fr" bundle will be used.

RequireJS also combines bundles together, so for instance, if the french bundle was defined like so (omitting a value for red):

//Contents of my/nls/fr-fr/colors.js
define({
    "blue": "bleu",
    "green": "vert"
});

Then the value for red in "root" will be used. This works for all locale pieces. If all the bundles listed below were defined, then RequireJS will use the values in the following priority order (the one at the top takes the most precedence):

  • my/nls/fr-fr-paris/colors.js
  • my/nls/fr-fr/colors.js
  • my/nls/fr/colors.js
  • my/nls/colors.js

If you prefer to not include the root bundle in the top level module, you can define it like a normal locale bundle. In that case, the top level module would look like:

//my/nls/colors.js contents:
define({
    "root": true,
    "fr-fr": true,
    "fr-fr-paris": true
});

and the root bundle would look like:

//Contents of my/nls/root/colors.js
define({
    "red": "red",
    "blue": "blue",
    "green": "green"
});

原文