बेहतर कंपाइलेशन

खास जानकारी

Closure Compiler का इस्तेमाल करने पर, compilation_level के साथ कंपाइल करने की तुलना में ADVANCED_OPTIMIZATIONS के साथ कंपाइल करने पर बेहतर कंप्रेशन रेट मिलते हैं. वहीं, SIMPLE_OPTIMIZATIONS या WHITESPACE_ONLY के साथ कंपाइल करने पर भी बेहतर कंप्रेशन रेट मिलते हैं. ADVANCED_OPTIMIZATIONS के साथ कंपाइल करने पर, कोड को बदलने और सिंबल का नाम बदलने के तरीके ज़्यादा बेहतर होते हैं. इसलिए, इससे ज़्यादा कंप्रेशन मिलता है. हालांकि, इस तरीके का इस्तेमाल करने पर आपको ADVANCED_OPTIMIZATIONS का इस्तेमाल करते समय ज़्यादा सावधानी बरतनी होगी. ऐसा इसलिए, ताकि यह पक्का किया जा सके कि आउटपुट कोड, इनपुट कोड की तरह ही काम करे.

इस ट्यूटोरियल में बताया गया है कि ADVANCED_OPTIMIZATIONS कंपाइलेशन लेवल क्या करता है. साथ ही, यह भी बताया गया है कि ADVANCED_OPTIMIZATIONS के साथ कंपाइल करने के बाद, यह पक्का करने के लिए क्या किया जा सकता है कि आपका कोड काम कर रहा है. इसमें extern के कॉन्सेप्ट के बारे में भी बताया गया है. यह एक ऐसा सिंबल है जिसे कंपाइलर से प्रोसेस किए गए कोड के बाहर के कोड में तय किया जाता है.

इस ट्यूटोरियल को पढ़ने से पहले, आपको JavaScript को कंपाइल करने की प्रोसेस के बारे में पता होना चाहिए. इसके लिए, आपको Closure Compiler टूल में से किसी एक का इस्तेमाल करना होगा. जैसे, Java पर आधारित compiler application.

शब्दावली के बारे में जानकारी: --compilation_level कमांड लाइन फ़्लैग, ज़्यादातर इस्तेमाल होने वाले छोटे नाम ADVANCED और SIMPLE के साथ-साथ ज़्यादा सटीक ADVANCED_OPTIMIZATIONS और SIMPLE_OPTIMIZATIONS के साथ काम करता है. इस दस्तावेज़ में लंबे फ़ॉर्म का इस्तेमाल किया गया है. हालांकि, कमांड लाइन पर नामों का इस्तेमाल एक-दूसरे के बदले किया जा सकता है.

  1. बेहतर कंप्रेशन
  2. ADVANCED_OPTIMIZATIONS को चालू करने का तरीका
  3. ADVANCED_OPTIMIZATIONS का इस्तेमाल करते समय किन बातों का ध्यान रखना चाहिए
    1. उस कोड को हटाना जिसे आपको रखना है
    2. प्रॉपर्टी के नाम अलग-अलग होना
    3. कोड के दो हिस्सों को अलग-अलग कंपाइल करना
    4. कंपाइल किए गए और कंपाइल नहीं किए गए कोड के बीच काम न करने वाले रेफ़रंस

बेहतर कंप्रेस करने की सुविधा

SIMPLE_OPTIMIZATIONS के डिफ़ॉल्ट कंपाइलेशन लेवल की मदद से, Closure Compiler लोकल वैरिएबल का नाम बदलकर JavaScript को छोटा कर देता है. स्थानीय वैरिएबल के अलावा, ऐसे अन्य सिंबल भी होते हैं जिन्हें छोटा किया जा सकता है. हालांकि, सिंबल का नाम बदलने के अलावा, कोड को छोटा करने के अन्य तरीके भी हैं. ADVANCED_OPTIMIZATIONS के साथ कंपाइल करने पर, कोड को छोटा करने की सभी सुविधाओं का इस्तेमाल किया जाता है.

नीचे दिए गए कोड के लिए, SIMPLE_OPTIMIZATIONS और ADVANCED_OPTIMIZATIONS के आउटपुट की तुलना करें:

function unusedFunction(note) {
  alert(note['text']);
}

function displayNoteTitle(note) {
  alert(note['title']);
}

var flowerNote = {};
flowerNote['title'] = "Flowers";
displayNoteTitle(flowerNote);

SIMPLE_OPTIMIZATIONS के साथ कंपाइल करने पर, कोड छोटा होकर यह हो जाता है:

function unusedFunction(a){alert(a.text)}function displayNoteTitle(a){alert(a.title)}var flowerNote={};flowerNote.title="Flowers";displayNoteTitle(flowerNote);

ADVANCED_OPTIMIZATIONS के साथ कंपाइल करने पर, कोड छोटा होकर यह बन जाता है:

alert("Flowers");

इन दोनों स्क्रिप्ट से "Flowers" वाली सूचना मिलती है. हालांकि, दूसरी स्क्रिप्ट का साइज़ बहुत छोटा है.

ADVANCED_OPTIMIZATIONS लेवल पर, वैरिएबल के नामों को कई तरीकों से छोटा किया जाता है. जैसे:

  • नाम बदलने की ज़्यादा बेहतर सुविधा:

    SIMPLE_OPTIMIZATIONS के साथ कंपाइल करने पर, सिर्फ़ displayNoteTitle() और unusedFunction() फ़ंक्शन के note पैरामीटर के नाम बदले जाते हैं. ऐसा इसलिए, क्योंकि स्क्रिप्ट में ये ऐसे वैरिएबल हैं जो किसी फ़ंक्शन के लिए लोकल होते हैं. ADVANCED_OPTIMIZATIONS, ग्लोबल वैरिएबल flowerNote का नाम भी बदलता है.

  • डेड कोड हटाने की सुविधा:

    ADVANCED_OPTIMIZATIONS के साथ कंपाइल करने पर, फ़ंक्शन unusedFunction() पूरी तरह से हट जाता है, क्योंकि इसे कोड में कभी कॉल नहीं किया जाता.

  • फ़ंक्शन इनलाइनिंग:

    ADVANCED_OPTIMIZATIONS के साथ कंपाइल करने पर, displayNoteTitle() को कॉल करने की जगह, फ़ंक्शन के मुख्य हिस्से को कंपोज़ करने वाले alert() का इस्तेमाल किया जाता है. फ़ंक्शन कॉल को फ़ंक्शन के मुख्य हिस्से से बदलने की इस प्रोसेस को "इनलाइनिंग" कहा जाता है. अगर फ़ंक्शन लंबा या ज़्यादा जटिल होता, तो उसे इनलाइन करने से कोड का व्यवहार बदल सकता था. हालांकि, Closure Compiler यह तय करता है कि इस मामले में इनलाइन करना सुरक्षित है और इससे जगह बचती है. कंपाइलेशन के दौरान, ADVANCED_OPTIMIZATIONS कुछ कॉन्स्टेंट और वैरिएबल को भी इनलाइन करता है. ऐसा तब होता है, जब उसे लगता है कि ऐसा सुरक्षित तरीके से किया जा सकता है.

यह सूची, साइज़ कम करने वाले ट्रांसफ़ॉर्मेशन का सिर्फ़ एक सैंपल है. ADVANCED_OPTIMIZATIONS कंपाइलर, इस तरह के कई ट्रांसफ़ॉर्मेशन कर सकता है.

ADVANCED_OPTIMIZATIONS मोड को चालू करने का तरीका

Closure Compiler ऐप्लिकेशन के लिए ADVANCED_OPTIMIZATIONS को चालू करने के लिए, कमांड लाइन फ़्लैग --compilation_level ADVANCED_OPTIMIZATIONS को शामिल करें. जैसे, यहां दी गई कमांड में:

java -jar compiler.jar --compilation_level ADVANCED_OPTIMIZATIONS --js hello.js

ADVANCED_OPTIMIZATIONS का इस्तेमाल करते समय किन बातों का ध्यान रखना चाहिए

यहां ADVANCED_OPTIMIZATIONS के कुछ सामान्य अनचाहे असर और उनसे बचने के तरीके दिए गए हैं.

उस कोड को हटाना जिसे आपको रखना है

अगर आपने नीचे दिए गए फ़ंक्शन को ADVANCED_OPTIMIZATIONS के साथ कंपाइल किया है, तो Closure Compiler से कोई आउटपुट नहीं मिलेगा:

function displayNoteTitle(note) {
  alert(note['myTitle']);
}

आपने कंपाइलर को जो JavaScript पास की है उसमें इस फ़ंक्शन को कभी कॉल नहीं किया जाता. इसलिए, Closure Compiler यह मान लेता है कि इस कोड की ज़रूरत नहीं है!

कई मामलों में, आपको यही व्यवहार चाहिए होता है. उदाहरण के लिए, अगर आपने अपने कोड को किसी बड़ी लाइब्रेरी के साथ कंपाइल किया है, तो Closure Compiler यह पता लगा सकता है कि आपने उस लाइब्रेरी के किन फ़ंक्शन का इस्तेमाल किया है. साथ ही, वह उन फ़ंक्शन को हटा सकता है जिनका इस्तेमाल नहीं किया गया है.

हालांकि, अगर आपको लगता है कि Closure Compiler उन फ़ंक्शन को हटा रहा है जिन्हें आपको रखना है, तो ऐसा होने से रोकने के लिए दो तरीके हैं:

  • अपने फ़ंक्शन कॉल को Closure Compiler से प्रोसेस किए गए कोड में ले जाएं.
  • जिन फ़ंक्शन को आपको दिखाना है उनके लिए, externs शामिल करें.

अगले सेक्शन में, हर विकल्प के बारे में ज़्यादा जानकारी दी गई है.

समाधान: अपने फ़ंक्शन कॉल को ऐसे कोड में ले जाएं जिसे Closure Compiler प्रोसेस करता है

अगर आपने अपने कोड के सिर्फ़ कुछ हिस्से को Closure Compiler की मदद से कंपाइल किया है, तो हो सकता है कि आपको अनचाहे कोड को हटाने की समस्या का सामना करना पड़े. उदाहरण के लिए, आपके पास एक ऐसी लाइब्रेरी फ़ाइल हो सकती है जिसमें सिर्फ़ फ़ंक्शन की परिभाषाएं शामिल हों. साथ ही, एक ऐसी एचटीएमएल फ़ाइल हो सकती है जिसमें लाइब्रेरी शामिल हो और जिसमें उन फ़ंक्शन को कॉल करने वाला कोड शामिल हो. इस मामले में, अगर लाइब्रेरी फ़ाइल को ADVANCED_OPTIMIZATIONS के साथ कंपाइल किया जाता है, तो Closure Compiler आपके सभी लाइब्रेरी फ़ंक्शन हटा देता है.

इस समस्या को हल करने का सबसे आसान तरीका यह है कि अपने फ़ंक्शन को प्रोग्राम के उस हिस्से के साथ कंपाइल करें जो उन फ़ंक्शन को कॉल करता है. उदाहरण के लिए, Closure Compiler इस प्रोग्राम को कंपाइल करते समय displayNoteTitle() को नहीं हटाएगा:

function displayNoteTitle(note) {
  alert(note['myTitle']);
}
displayNoteTitle({'myTitle': 'Flowers'});

इस मामले में, displayNoteTitle() फ़ंक्शन को नहीं हटाया जाता, क्योंकि Closure Compiler देखता है कि इसे कॉल किया गया है.

दूसरे शब्दों में कहें, तो अनचाहे कोड को हटाने से रोकने के लिए, अपने प्रोग्राम के एंट्री पॉइंट को उस कोड में शामिल करें जिसे आपको Closure Compiler को पास करना है. प्रोग्राम का एंट्री पॉइंट, कोड में वह जगह होती है जहां से प्रोग्राम को एक्ज़ीक्यूट करना शुरू किया जाता है. उदाहरण के लिए, पिछले सेक्शन में दिए गए फ़्लावर नोट प्रोग्राम में, JavaScript के ब्राउज़र में लोड होते ही आखिरी तीन लाइनें एक्ज़ीक्यूट हो जाती हैं. यह इस प्रोग्राम का एंट्री पॉइंट है. Closure Compiler यह तय करता है कि आपको कौन सा कोड रखना है. इसके लिए, वह इस एंट्री पॉइंट से शुरू होता है और प्रोग्राम के कंट्रोल फ़्लो को आगे बढ़ाता है.

समाधान: जिन फ़ंक्शन को आपको दिखाना है उनके लिए Externs शामिल करें

इस समाधान के बारे में ज़्यादा जानकारी यहां और externs और exports पेज पर दी गई है.

प्रॉपर्टी के नामों में अंतर होना

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

उदाहरण के लिए, यहां दिया गया कोड देखें:

function displayNoteTitle(note) {
  alert(note['myTitle']);
}
var flowerNote = {};
flowerNote.myTitle = 'Flowers';

alert(flowerNote.myTitle);
displayNoteTitle(flowerNote);

इस सोर्स कोड में, आखिरी दो स्टेटमेंट एक ही काम करते हैं. हालांकि, ADVANCED_OPTIMIZATIONS की मदद से कोड को कंप्रेस करने पर, आपको यह मिलता है:

var a={};a.a="Flowers";alert(a.a);alert(a.myTitle);

कंप्रेस किए गए कोड में मौजूद आखिरी स्टेटमेंट से गड़बड़ी होती है. myTitle प्रॉपर्टी के डायरेक्ट रेफ़रंस का नाम बदलकर a कर दिया गया है. हालांकि, displayNoteTitle फ़ंक्शन में myTitle के कोट किए गए रेफ़रंस का नाम नहीं बदला गया है. इस वजह से, आखिरी स्टेटमेंट में ऐसी myTitle प्रॉपर्टी का रेफ़रंस दिया गया है जो अब मौजूद नहीं है.

समाधान: अपनी प्रॉपर्टी के नामों में एक जैसा फ़ॉर्मैट इस्तेमाल करें

यह तरीका बहुत आसान है. किसी भी टाइप या ऑब्जेक्ट के लिए, सिर्फ़ डॉट-सिंटैक्स या कोट की गई स्ट्रिंग का इस्तेमाल करें. सिंटैक्स को मिक्स न करें. खास तौर पर, एक ही प्रॉपर्टी के रेफ़रंस में.

साथ ही, जब भी हो सके, डॉट-सिंटैक्स का इस्तेमाल करें. इससे बेहतर जांच और ऑप्टिमाइज़ेशन में मदद मिलती है. कोट की गई स्ट्रिंग प्रॉपर्टी ऐक्सेस का इस्तेमाल सिर्फ़ तब करें, जब आपको Closure Compiler से नाम बदलने का काम नहीं कराना हो. जैसे, जब नाम किसी बाहरी सोर्स से आता है, जैसे कि डिकोड किया गया JSON.

कोड के दो हिस्सों को अलग-अलग कंपाइल करना

अगर आपने अपने ऐप्लिकेशन को कोड के अलग-अलग हिस्सों में बांटा है, तो हो सकता है कि आपको उन हिस्सों को अलग-अलग कंपाइल करना पड़े. हालांकि, अगर कोड के दो हिस्सों के बीच कोई इंटरैक्शन होता है, तो ऐसा करने से समस्या हो सकती है. अगर आप ऐसा कर भी लेते हैं, तो Closure Compiler के दो वर्शन के आउटपुट एक-दूसरे के साथ काम नहीं करेंगे.

उदाहरण के लिए, मान लें कि किसी ऐप्लिकेशन को दो हिस्सों में बांटा गया है: एक हिस्सा डेटा को वापस पाने का काम करता है और दूसरा हिस्सा डेटा को दिखाने का काम करता है.

डेटा वापस पाने का कोड यहां दिया गया है:

function getData() {
  // In an actual project, this data would be retrieved from the server.
  return {title: 'Flower Care', text: 'Flowers need water.'};
}

डेटा दिखाने के लिए यहां कोड दिया गया है:

var displayElement = document.getElementById('display');
function displayData(parent, data) {
  var textElement = document.createTextNode(data.text);
  parent.appendChild(textElement);
}
displayData(displayElement, getData());

अगर इन दोनों कोड को अलग-अलग कंपाइल किया जाता है, तो आपको कई समस्याएं आएंगी. सबसे पहले, Closure Compiler getData() फ़ंक्शन को हटाता है. इसकी वजहें आपको जिस कोड को रखना है उसे हटाना में बताई गई हैं. दूसरा, डेटा दिखाने वाले कोड को प्रोसेस करते समय, Closure Compiler एक गंभीर गड़बड़ी करता है.

input:6: ERROR - variable getData is undefined
displayData(displayElement, getData());

डेटा दिखाने वाले कोड को कंपाइल करते समय, कंपाइलर के पास getData() फ़ंक्शन का ऐक्सेस नहीं होता. इसलिए, वह getData को अपरिभाषित के तौर पर मानता है.

समस्या हल करने का तरीका: पेज के सभी कोड को एक साथ कंपाइल करें

सही तरीके से कंपाइल करने के लिए, किसी पेज के सभी कोड को एक साथ कंपाइल करें. Closure Compiler, इनपुट के तौर पर कई JavaScript फ़ाइलें और JavaScript स्ट्रिंग स्वीकार कर सकता है. इसलिए, एक ही कंपाइलेशन अनुरोध में लाइब्रेरी कोड और अन्य कोड एक साथ पास किया जा सकता है.

ध्यान दें: अगर आपको कंपाइल किए गए और कंपाइल न किए गए कोड को एक साथ इस्तेमाल करना है, तो यह तरीका काम नहीं करेगा. इस समस्या को ठीक करने के बारे में सलाह पाने के लिए, कंपाइल किए गए और कंपाइल नहीं किए गए कोड के बीच टूटे हुए रेफ़रंस देखें.

कंपाइल किए गए और कंपाइल नहीं किए गए कोड के बीच काम न करने वाले रेफ़रंस

ADVANCED_OPTIMIZATIONS में सिंबल का नाम बदलने से, Closure Compiler और किसी अन्य कोड के बीच कम्यूनिकेशन नहीं हो पाएगा. कंपाइलेशन, आपके सोर्स कोड में तय किए गए फ़ंक्शन के नाम बदल देता है. आपके फ़ंक्शन को कॉल करने वाला कोई भी बाहरी कोड, कंपाइल करने के बाद काम नहीं करेगा. ऐसा इसलिए, क्योंकि वह अब भी फ़ंक्शन के पुराने नाम का इस्तेमाल कर रहा है. इसी तरह, कंपाइल किए गए कोड में बाहरी तौर पर तय किए गए सिंबल के रेफ़रंस में Closure Compiler बदलाव कर सकता है.

ध्यान रखें कि "अनकंपाइल किया गया कोड" में, eval() फ़ंक्शन को स्ट्रिंग के तौर पर पास किया गया कोई भी कोड शामिल होता है. Closure Compiler, कोड में मौजूद स्ट्रिंग लिटरल में कभी बदलाव नहीं करता. इसलिए, Closure Compiler, eval() स्टेटमेंट को पास की गई स्ट्रिंग में बदलाव नहीं करता.

ध्यान दें कि ये समस्याएं एक-दूसरे से जुड़ी हैं, लेकिन अलग-अलग हैं: कंपाइल किए गए कोड से बाहरी कम्यूनिकेशन को बनाए रखना और बाहरी कम्यूनिकेशन से कंपाइल किए गए कोड को बनाए रखना. इन अलग-अलग समस्याओं का एक ही समाधान है. हालांकि, हर समस्या के लिए अलग-अलग बारीकियां हैं. Closure Compiler का ज़्यादा से ज़्यादा फ़ायदा पाने के लिए, यह समझना ज़रूरी है कि आपके पास कौनसी सुविधा है.

आगे बढ़ने से पहले, externs और exports के बारे में जान लें.

कंपाइल किए गए कोड से बाहरी कोड को कॉल करने का तरीका: Externs के साथ कंपाइल करना

अगर किसी दूसरी स्क्रिप्ट से मिले कोड का इस्तेमाल किया जाता है, तो आपको यह पक्का करना होगा कि Closure Compiler, बाहरी लाइब्रेरी में तय किए गए सिंबल के रेफ़रंस का नाम न बदले. इसके लिए, बाहरी लाइब्रेरी के लिए एक्सटर्न फ़ाइल को अपने कंपाइलेशन में शामिल करें. इससे Closure Compiler को पता चलेगा कि किन नामों को कंट्रोल नहीं किया जा सकता. इसलिए, उन्हें बदला नहीं जा सकता. आपके कोड में वही नाम इस्तेमाल किए जाने चाहिए जो बाहरी फ़ाइल में इस्तेमाल किए गए हैं.

इसके सामान्य उदाहरणों में, OpenSocial API और Google Maps API जैसे एपीआई शामिल हैं. उदाहरण के लिए, अगर आपका कोड OpenSocial फ़ंक्शन opensocial.newDataRequest() को कॉल करता है, तो सही एक्सटर्न के बिना, Closure Compiler इस कॉल को a.b() में बदल देगा.

बाहरी कोड से कंपाइल किए गए कोड को कॉल करने का तरीका: Externs लागू करना

अगर आपके पास ऐसा JavaScript कोड है जिसे लाइब्रेरी के तौर पर फिर से इस्तेमाल किया जाता है, तो आपको सिर्फ़ लाइब्रेरी को छोटा करने के लिए Closure Compiler का इस्तेमाल करना पड़ सकता है. साथ ही, बिना कंपाइल किए गए कोड को लाइब्रेरी में फ़ंक्शन कॉल करने की अनुमति देनी पड़ सकती है.

ऐसी स्थिति में, आपकी लाइब्रेरी के सार्वजनिक एपीआई को तय करने वाले एक्सटर्न का सेट लागू करना ही समाधान है. आपका कोड, इन बाहरी फ़ाइलों में घोषित किए गए सिंबल के लिए परिभाषाएं देगा. इसका मतलब है कि आपके इंटर्न ने जिन क्लास या फ़ंक्शन के बारे में बताया है. इसका यह मतलब भी हो सकता है कि आपकी क्लास में, externs में बताए गए इंटरफ़ेस लागू किए गए हों.

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

इसके लिए, पक्का करें कि कोड को कंपाइल करते समय, कंपाइलेशन में बाहरी फ़ाइलें भी शामिल हों. यह अजीब लग सकता है, क्योंकि हम अक्सर एक्सटर्न को "कहीं और से आने वाले" के तौर पर देखते हैं. हालांकि, Closure Compiler को यह बताना ज़रूरी है कि आपने किन सिंबल को ऐक्सेस करने की अनुमति दी है, ताकि उनका नाम न बदला जाए.

यहां एक ज़रूरी चेतावनी यह है कि आपको बाहरी सिंबल को तय करने वाले कोड के बारे में "डुप्लीकेट परिभाषा" वाली डाइग्नोस्टिक्स मिल सकती हैं. Closure Compiler यह मानता है कि externs में मौजूद किसी भी सिंबल को बाहरी लाइब्रेरी से सप्लाई किया जा रहा है. फ़िलहाल, यह नहीं समझ पा रहा है कि आपने जान-बूझकर कोई परिभाषा दी है. इन डाइग्नोस्टिक्स को छिपाना सुरक्षित है. साथ ही, इन्हें छिपाने का मतलब यह है कि आपने एपीआई की शर्तों को पूरा कर लिया है.

इसके अलावा, Closure Compiler यह भी टाइपचेक कर सकता है कि आपकी परिभाषाएं, बाहरी घोषणाओं के टाइप से मेल खाती हैं या नहीं. इससे यह पुष्टि करने में मदद मिलती है कि आपकी परिभाषाएं सही हैं.