क्या आपको कभी यह महसूस हुआ है कि क्लाइंट-साइड कोड को जोड़ने और छोटा करने के बाद भी, उसे पढ़ा जा सकता है और सबसे ज़रूरी बात यह है कि परफ़ॉर्मेंस पर असर डाले बिना उसे डीबग किया जा सकता है? अब सोर्स मैप की मदद से, ऐसा किया जा सकता है.
सोर्स मैप, किसी छोटी/मर्ज की गई फ़ाइल को वापस बिना बिल्ट किए गए स्टेटस में मैप करने का एक तरीका है. प्रोडक्शन के लिए बिल्ड करने पर, JavaScript फ़ाइलों को छोटा करने और उन्हें आपस में जोड़ने के साथ-साथ, एक सोर्स मैप जनरेट होता है. इसमें आपकी ओरिजनल फ़ाइलों की जानकारी होती है. जनरेट किए गए JavaScript में किसी लाइन और कॉलम नंबर के बारे में क्वेरी करने पर, सोर्स मैप में लुकअप किया जा सकता है. इससे, मूल जगह की जानकारी मिलती है. डेवलपर टूल (फ़िलहाल WebKit के हर रात बनाए जाने वाले बिल्ड, Google Chrome या Firefox 23+) सोर्स मैप को अपने-आप पार्स कर सकते हैं. इससे ऐसा लगता है कि आपने बिना छोटी की गई और बिना जोड़ी गई फ़ाइलें चलाई हैं.
डेमो में, जनरेट किए गए सोर्स वाले टेक्स्टएरिया में कहीं भी राइट क्लिक किया जा सकता है. "ओरिजनल लोकेशन पाएं" चुनने पर, जनरेट की गई लाइन और कॉलम नंबर को सोर्स मैप में भेजकर क्वेरी की जाएगी. साथ ही, ओरिजनल कोड में पोज़िशन दिखाएगी. पक्का करें कि आपका कंसोल खुला हो, ताकि आपको आउटपुट दिख सके.
असल दुनिया
सोर्स मैप को असल दुनिया में लागू करने के बारे में यहां बताया गया है. इसे देखने से पहले, पक्का करें कि आपने Chrome Canary या WebKit nightly में सोर्स मैप की सुविधा चालू की हो. इसके लिए, डेवलपर टूल पैनल में सेटिंग के ऐरो पर क्लिक करें और "सोर्स मैप चालू करें" विकल्प को चुनें.
Firefox 23 और उसके बाद के वर्शन में, पहले से मौजूद डेवलपर टूल में सोर्स मैप डिफ़ॉल्ट रूप से चालू होते हैं.
मुझे सोर्स मैप की ज़रूरत क्यों पड़ेगी?
फ़िलहाल, सोर्स मैपिंग सिर्फ़ अनकंप्रेस किए गए/कॉम्बाइन किए गए JavaScript से कंप्रेस किए गए/कॉम्बाइन नहीं किए गए JavaScript के बीच काम कर रही है. हालांकि, आने वाले समय में इसकी संभावना है कि CoffeeScript जैसी JavaScript में कंपाइल की गई भाषाओं के साथ-साथ, SASS या LESS जैसे सीएसएस प्रीप्रोसेसर के लिए भी सहायता जोड़ी जाए.
आने वाले समय में, हम किसी भी भाषा का इस्तेमाल आसानी से कर पाएंगे. ऐसा लगेगा कि वह सोर्स मैप के साथ ब्राउज़र में नेटिव तौर पर काम करती है:
- CoffeeScript
- ECMAScript 6 और उसके बाद के वर्शन
- SASS/LESS और अन्य
- ऐसी कोई भी भाषा जो JavaScript में कंपाइल होती है
Firefox कंसोल के एक्सपेरिमेंटल बिल्ड में, CoffeeScript को डीबग किए जाने के इस स्क्रीनकास्ट को देखें:
Google Web Toolkit (GWT) में हाल ही में सोर्स मैप के लिए सहायता जोड़ी गई है. GWT टीम के रे क्रॉमवेल ने एक बेहतरीन स्क्रीनकास्ट किया है. इसमें, सोर्स मैप की सुविधा को काम करते हुए दिखाया गया है.
मैंने एक और उदाहरण दिया है, जिसमें Google की Traceur लाइब्रेरी का इस्तेमाल किया गया है. इसकी मदद से, ES6 (ECMAScript 6 या Next) को लिखा जा सकता है और इसे ES3 के साथ काम करने वाले कोड में कंपाइल किया जा सकता है. Traceur कंपाइलर, सोर्स मैप भी जनरेट करता है. सोर्स मैप की मदद से, ES6 के ट्रैट और क्लास का इस्तेमाल ब्राउज़र में नेटिव तौर पर किया जा सकता है. इस डेमो में, इसका उदाहरण दिया गया है.
डेमो में मौजूद टेक्स्टएरिया में, ES6 कोड भी लिखा जा सकता है. इसे तुरंत कॉम्पाइल किया जाएगा और एक सोर्स मैप के साथ-साथ, ES3 कोड भी जनरेट किया जाएगा.
डेमो: ES6 लिखना, उसे डीबग करना, और सोर्स मैपिंग को काम करते हुए देखना
सोर्स मैप कैसे काम करता है?
फ़िलहाल, सोर्स मैप जनरेट करने के लिए, Closure कंपाइलर ही एक ऐसा JavaScript कंपाइलर/मिनिफ़ायर है जो काम करता है. (हम इसका इस्तेमाल करने का तरीका बाद में बताएंगे.) JavaScript को जोड़ने और छोटा करने के बाद, उसके साथ एक सोर्स मैप फ़ाइल मौजूद होगी.
फ़िलहाल, Closure कंपाइलर आखिर में वह खास टिप्पणी नहीं जोड़ता जो ब्राउज़र के डेवलपर टूल को यह बताने के लिए ज़रूरी है कि सोर्स मैप उपलब्ध है:
//# sourceMappingURL=/path/to/file.js.map
इससे डेवलपर टूल, कॉल को ओरिजनल सोर्स फ़ाइलों में उनकी जगह पर मैप कर पाते हैं. पहले, टिप्पणी के लिए प्रैगमा //@
था. हालांकि, उसमें कुछ समस्याएं थीं और IE की शर्तों के मुताबिक कंपाइल करने की टिप्पणियों की वजह से, इसे //#
में बदलने का फ़ैसला लिया गया. फ़िलहाल, Chrome Canary, WebKit Nightly, और Firefox 24 और उसके बाद के वर्शन, नए कमेंट्री प्रैगमा के साथ काम करते हैं. सिंटैक्स में हुए इस बदलाव का असर sourceURL पर भी पड़ता है.
अगर आपको अजीब टिप्पणी का आइडिया पसंद नहीं है, तो इसके बजाय अपनी कंपाइल की गई JavaScript फ़ाइल पर एक खास हेडर सेट किया जा सकता है:
X-SourceMap: /path/to/file.js.map
टिप्पणी की तरह, यह आपके सोर्स मैप कंज्यूमर को बताएगा कि किसी JavaScript फ़ाइल से जुड़े सोर्स मैप को कहां देखना है. इस हेडर की मदद से, उन भाषाओं में सोर्स मैप का रेफ़रंस देने की समस्या को भी हल किया जा सकता है जिनमें एक लाइन की टिप्पणियां काम नहीं करतीं.
सोर्स मैप फ़ाइल सिर्फ़ तब डाउनलोड होगी, जब आपने सोर्स मैप की सुविधा चालू की हो और आपके डेवलपर टूल खुले हों. आपको अपनी ओरिजनल फ़ाइलें भी अपलोड करनी होंगी, ताकि डेवलपर टूल ज़रूरत पड़ने पर उनका रेफ़रंस दे सकें और उन्हें दिखा सकें.
मैं सोर्स मैप कैसे जनरेट करूं?
आपको अपनी JavaScript फ़ाइलों को छोटा करने, जोड़ने, और सोर्स मैप जनरेट करने के लिए, Closure कंपाइलर का इस्तेमाल करना होगा. निर्देश इस तरह का है:
java -jar compiler.jar \
--js script.js \
--create_source_map ./script-min.js.map \
--source_map_format=V3 \
--js_output_file script-min.js
दो अहम कमांड फ़्लैग, --create_source_map
और --source_map_format
हैं. ऐसा करना ज़रूरी है, क्योंकि डिफ़ॉल्ट वर्शन V2 है और हम सिर्फ़ V3 के साथ काम करना चाहते हैं.
सोर्स मैप की बनावट
सोर्स मैप को बेहतर तरीके से समझने के लिए, हम एक सोर्स मैप फ़ाइल का एक छोटा उदाहरण लेंगे. यह फ़ाइल, Closure कंपाइलर से जनरेट होगी. साथ ही, हम "मैपिंग" सेक्शन के काम करने के तरीके के बारे में ज़्यादा जानकारी देंगे. यहां दिया गया उदाहरण, V3 स्पेसिफ़िकेशन के उदाहरण से थोड़ा अलग है.
{
version : 3,
file: "out.js",
sourceRoot : "",
sources: ["foo.js", "bar.js"],
names: ["src", "maps", "are", "fun"],
mappings: "AAgBC,SAAQ,CAAEA"
}
ऊपर दिए गए उदाहरण से पता चलता है कि सोर्स मैप एक ऑब्जेक्ट लिटरल है, जिसमें बहुत सारी अहम जानकारी होती है:
- सोर्स मैप जिस वर्शन पर आधारित है
- जनरेट किए गए कोड की फ़ाइल का नाम (आपकी छोटी/कॉम्बाइन की गई प्रोडक्शन फ़ाइल)
- sourceRoot की मदद से, सोर्स को फ़ोल्डर स्ट्रक्चर के साथ जोड़ा जा सकता है - यह जगह बचाने की एक तकनीक भी है
- sources में, उन सभी फ़ाइलों के नाम शामिल होते हैं जिन्हें आपस में जोड़ा गया था
- names में वे सभी वैरिएबल/मेथड के नाम होते हैं जो आपके पूरे कोड में दिखते हैं.
- आखिर में, मैपिंग प्रॉपर्टी में Base64 VLQ वैल्यू का इस्तेमाल करके जादू होता है. असल में, जगह की बचत यहां होती है.
Base64 VLQ और सोर्स मैप को छोटा रखना
मूल रूप से, सोर्स मैप स्पेसिफ़िकेशन में सभी मैपिंग का बहुत लंबा आउटपुट होता था. इस वजह से, सोर्स मैप का साइज़, जनरेट किए गए कोड के साइज़ से करीब 10 गुना ज़्यादा होता था. दूसरे वर्शन में, इस साइज़ को करीब 50% कम कर दिया गया. तीसरे वर्शन में, इसे फिर से 50% कम कर दिया गया. इसलिए, 133 केबी की फ़ाइल के लिए, आपको ~300 केबी का सोर्स मैप मिलता है.
तो उन्होंने जटिल मैपिंग को बनाए रखते हुए, साइज़ को कैसे कम किया?
वैल्यू को Base64 वैल्यू में एन्कोड करने के साथ-साथ, VLQ (वैरिएबल लेंथ क्वांटिटी) का इस्तेमाल किया जाता है. मैपिंग प्रॉपर्टी बहुत बड़ी स्ट्रिंग होती है. इस स्ट्रिंग में सेमीकोलन (;) होते हैं, जो जनरेट की गई फ़ाइल में लाइन नंबर दिखाते हैं. हर लाइन में कॉमा (,) होते हैं, जो उस लाइन के हर सेगमेंट को दिखाते हैं. वैरिएबल लंबाई वाले फ़ील्ड में, इनमें से हर सेगमेंट 1, 4 या 5 होता है. कुछ वीडियो लंबे लग सकते हैं, लेकिन इनमें वीडियो के बीच में काटा गया कॉन्टेंट भी शामिल होता है. हर सेगमेंट, पिछले सेगमेंट के आधार पर बनता है. इससे फ़ाइल का साइज़ कम करने में मदद मिलती है, क्योंकि हर बिट अपने पिछले सेगमेंट से जुड़ा होता है.
जैसा कि ऊपर बताया गया है, हर सेगमेंट की लंबाई 1, 4 या 5 हो सकती है. इस डायग्राम को चार वर्िएबल लंबाई के साथ एक कंटिन्यूएशन बिट (g) माना जाता है. हम इस सेगमेंट को अलग-अलग हिस्सों में बांटकर, आपको बताएंगे कि सोर्स मैप, मूल जगह की जानकारी कैसे देता है.
ऊपर दिखाई गई वैल्यू, Base64 से डिकोड की गई वैल्यू हैं. इनकी सही वैल्यू पाने के लिए, कुछ और प्रोसेसिंग की ज़रूरत होती है. आम तौर पर, हर सेगमेंट में ये पांच चीज़ें शामिल होती हैं:
- जनरेट किया गया कॉलम
- वह ओरिजनल फ़ाइल जिसमें यह गड़बड़ी दिखी
- ओरिजनल लाइन नंबर
- ओरिजनल कॉलम
- अगर उपलब्ध हो, तो मूल नाम
हर सेगमेंट का नाम, तरीका का नाम या आर्ग्युमेंट नहीं होता. इसलिए, पूरे सेगमेंट में चार से पांच वैरिएबल की लंबाई के बीच स्विच किया जाएगा. ऊपर दिए गए सेगमेंट डायग्राम में g वैल्यू को कंटिन्यूएशन बिट कहा जाता है. इससे Base64 VLQ डिकोडिंग स्टेज में ज़्यादा ऑप्टिमाइज़ेशन की सुविधा मिलती है. कंटिन्यूएशन बिट की मदद से, सेगमेंट वैल्यू को बढ़ाया जा सकता है. इससे, बड़ी संख्या को स्टोर किए बिना ही बड़ी संख्या स्टोर की जा सकती है. यह स्पेस बचाने की एक बहुत ही बेहतरीन तकनीक है, जिसकी शुरुआत मिडी फ़ॉर्मैट से हुई थी.
ऊपर दिए गए डायग्राम AAgBC
को प्रोसेस करने के बाद, 0, 0, 32, 16, 1 वैल्यू दिखेगी. 32, कंटिन्यूएशन बिट है, जो 16 की वैल्यू बनाने में मदद करता है. Base64 में पूरी तरह से डिकोड किया गया B, 1 है. इसलिए, इस्तेमाल की जाने वाली ज़रूरी वैल्यू 0, 0, 16, 1 हैं. इससे हमें पता चलता है कि जनरेट की गई फ़ाइल की लाइन 1 (लाइनों की गिनती सेमी कोलन से की जाती है) कॉलम 0, फ़ाइल 0 (फ़ाइलों का कलेक्शन 0, foo.js है) कॉलम 1 की लाइन 16 से मैप होती है.
सेगमेंट को डिकोड करने का तरीका दिखाने के लिए, मैं Mozilla की सोर्स मैप JavaScript लाइब्रेरी का रेफ़रंस दूंगा. WebKit डेवलपर टूल का सोर्स मैपिंग कोड भी देखा जा सकता है. इसे भी JavaScript में लिखा गया है.
B से 16 की वैल्यू कैसे मिलती है, यह समझने के लिए हमें बिटवाइज़ ऑपरेटर के बारे में बुनियादी जानकारी होनी चाहिए. साथ ही, यह भी जानना चाहिए कि सोर्स मैपिंग के लिए स्पेसिफ़िकेशन कैसे काम करता है. बिटवाइज़ AND (&) ऑपरेटर का इस्तेमाल करके, अंक (32) और VLQ_CONTINUATION_BIT (बाइनरी 100000 या 32) की तुलना करके, पिछले अंक g को बिट के तौर पर फ़्लैग किया जाता है.
32 & 32 = 32
// or
100000
|
|
V
100000
यह हर उस बिट पोज़िशन में 1 दिखाता है जहां दोनों में यह दिखता है. इसलिए, 33 & 32
की Base64 डिकोड की गई वैल्यू 32 होगी, क्योंकि ऊपर दिए गए डायग्राम में देखा जा सकता है कि वे सिर्फ़ 32 बिट की जगह शेयर करते हैं. इससे, पहले के हर कंटिन्यूएशन बिट के लिए, बिट शिफ़्ट वैल्यू को पांच बढ़ा दिया जाता है. ऊपर दिए गए मामले में, इसे सिर्फ़ एक बार पांच से शिफ़्ट किया गया है. इसलिए, 1 (B) को बाईं ओर पांच से शिफ़्ट किया गया है.
1 <<../ 5 // 32
// Shift the bit by 5 spots
______
| |
V V
100001 = 100000 = 32
इसके बाद, उस वैल्यू को VLQ साइन वाली वैल्यू से बदला जाता है. इसके लिए, संख्या (32) को दाईं ओर एक स्थान पर शिफ़्ट किया जाता है.
32 >> 1 // 16
//or
100000
|
|
V
010000 = 16
तो यह रहा तरीका: इस तरह से 1 को 16 में बदला जा सकता है. यह प्रोसेस ज़्यादा मुश्किल लग सकती है, लेकिन संख्याएं बड़ी होने पर यह ज़्यादा काम की हो जाती है.
XSSI से जुड़ी संभावित समस्याएं
स्पेसिफ़िकेशन में, क्रॉस साइट स्क्रिप्ट को शामिल करने से जुड़ी समस्याओं के बारे में बताया गया है. ये समस्याएं, सोर्स मैप का इस्तेमाल करने से हो सकती हैं. इसे कम करने के लिए, हमारा सुझाव है कि आप अपने सोर्स मैप की पहली लाइन में ")]}
" जोड़ें. इससे JavaScript को जान-बूझकर अमान्य कर दिया जाएगा, ताकि सिंटैक्स से जुड़ी गड़बड़ी दिखे. WebKit डेवलपर टूल, पहले से ही इस काम को मैनेज कर सकते हैं.
if (response.slice(0, 3) === ")]}") {
response = response.substring(response.indexOf('\n'));
}
ऊपर दिखाए गए उदाहरण में, पहले तीन वर्णों को काटकर यह जांच की जाती है कि वे खास जानकारी में मौजूद सिंटैक्स की गड़बड़ी से मेल खाते हैं या नहीं. अगर ऐसा होता है, तो पहली नई लाइन इकाई (\n) से पहले के सभी वर्णों को हटा दिया जाता है.
sourceURL
और displayName
का इस्तेमाल: Eval और बिना नाम वाले फ़ंक्शन
ये दो कॉन्वेंशन, सोर्स मैप स्पेसिफ़िकेशन का हिस्सा नहीं हैं. हालांकि, इनकी मदद से, evals और अनाम फ़ंक्शन के साथ काम करते समय डेवलपमेंट को आसान बनाया जा सकता है.
पहला हेल्पर, //# sourceMappingURL
प्रॉपर्टी से काफ़ी मिलता-जुलता है. साथ ही, इसका ज़िक्र सोर्स मैप V3 स्पेसिफ़िकेशन में किया गया है. अपने कोड में नीचे दी गई खास टिप्पणी शामिल करके, जिसे एवल्यू किया जाएगा, आपके पास एवल्यू को नाम देने का विकल्प होता है, ताकि वे आपके डेवलपर टूल में ज़्यादा लॉजिकल नामों के तौर पर दिखें. CoffeeScript कंपाइलर का इस्तेमाल करके, एक आसान डेमो देखें:
डेमो: sourceURL के ज़रिए, eval()
का कोड स्क्रिप्ट के तौर पर देखें
//# sourceURL=sqrt.coffee
दूसरे हेल्पर की मदद से, नाम नहीं वाले फ़ंक्शन को नाम दिया जा सकता है. इसके लिए, नाम नहीं वाले फ़ंक्शन के मौजूदा कॉन्टेक्स्ट में उपलब्ध displayName
प्रॉपर्टी का इस्तेमाल किया जाता है. displayName
प्रॉपर्टी को काम करते हुए देखने के लिए, यहां दिए गए डेमो की प्रोफ़ाइल बनाएं.
btns[0].addEventListener("click", function(e) {
var fn = function() {
console.log("You clicked button number: 1");
};
fn.displayName = "Anonymous function of button 1";
return fn();
}, false);
डेवलपर टूल में अपने कोड की प्रोफ़ाइल बनाते समय, (anonymous)
के बजाय displayName
प्रॉपर्टी दिखेगी. हालांकि, displayName का इस्तेमाल अब नहीं किया जा सकता. इसे Chrome में भी इस्तेमाल नहीं किया जाएगा. हालांकि, पूरी उम्मीद नहीं छोड़ी जानी चाहिए. एक बेहतर सुझाव दिया गया है, जिसे debugName कहा जाता है.
फ़िलहाल, eval नाम देने की सुविधा सिर्फ़ Firefox और WebKit ब्राउज़र में उपलब्ध है. displayName
प्रॉपर्टी सिर्फ़ WebKit के नाइटली वर्शन में उपलब्ध है.
आइए, मिलकर काम करें
फ़िलहाल, CoffeeScript में सोर्स मैप की सुविधा जोड़ने के बारे में बहुत लंबी चर्चा चल रही है. समस्या देखें और CoffeeScript कंपाइलर में सोर्स मैप जनरेशन की सुविधा जोड़ने के लिए, अपनी मदद जोड़ें. यह CoffeeScript और इसके प्रशंसकों के लिए एक बड़ी जीत होगी.
UglifyJS में भी सोर्स मैप से जुड़ी समस्या है. आपको इस पर भी ध्यान देना चाहिए.
कई टूल सोर्स मैप जनरेट करते हैं. इनमें coffeescript कंपाइलर भी शामिल है. मुझे लगता है कि अब इस बात का कोई मतलब नहीं है.
हमारे पास जितने ज़्यादा सोर्स मैप जनरेट करने वाले टूल होंगे, हम उतने ही बेहतर तरीके से काम कर पाएंगे. इसलिए, अपने पसंदीदा ओपन सोर्स प्रोजेक्ट में सोर्स मैप की सुविधा जोड़ें या इसके लिए सहायता मांगें.
यह पूरी तरह से सही नहीं है
फ़िलहाल, सोर्स मैप में वॉच एक्सप्रेशन का इस्तेमाल नहीं किया जा सकता. समस्या यह है कि मौजूदा एक्सीक्यूशन कॉन्टेक्स्ट में किसी आर्ग्युमेंट या वैरिएबल के नाम की जांच करने पर, कुछ भी नहीं दिखेगा, क्योंकि वह असल में मौजूद नहीं है. इसके लिए, आपको किसी तरह की रिवर्स मैपिंग की ज़रूरत होगी, ताकि आप उस आर्ग्युमेंट/वैरिएबल का असली नाम देख सकें जिसकी आपको जांच करनी है. यह नाम, आपके कंपाइल किए गए JavaScript में मौजूद आर्ग्युमेंट/वैरिएबल के असली नाम से अलग होता है.
यह समस्या हल की जा सकती है. सोर्स मैप पर ज़्यादा ध्यान देने से, हमें कुछ बेहतरीन सुविधाएं और बेहतर स्थिरता मिल सकती है.
समस्याएं
हाल ही में, jQuery 1.9 में, आधिकारिक सीडीएन से सोर्स मैप को दिखाने की सुविधा जोड़ी गई है. इससे, jQuery लोड होने से पहले IE की कंडीशनल कंपाइलेशन टिप्पणियों (//@cc_on) का इस्तेमाल करने पर, एक खास बग का पता चला. इसके बाद, sourceMappingURL को कई लाइन वाली टिप्पणी में रैप करके, इस समस्या को कम करने के लिए एक commit किया गया है. सीख: शर्त के हिसाब से टिप्पणी करने की सुविधा का इस्तेमाल न करें.
सिंटैक्स को //#
में बदलकर, इस समस्या को ठीक कर दिया गया है.
टूल और संसाधन
यहां कुछ और संसाधन और टूल दिए गए हैं जिन्हें आपको देखना चाहिए:
- निक फ़िट्जगेराल्ड के पास UglifyJS का एक फ़ॉर्क है, जिसमें सोर्स मैप की सुविधा है
- पॉल आयरिश ने सोर्स मैप दिखाने के लिए एक छोटा डेमो बनाया है
- WebKit में इस सुविधा के हटने के समय की बदलाव सूची देखें
- बदलावों की सूची में एक लेआउट टेस्ट भी शामिल था, जिसकी वजह से यह पूरा लेख शुरू हुआ
- Mozilla में एक बग है. आपको पहले से मौजूद कंसोल में सोर्स मैप की स्थिति पर नज़र रखनी चाहिए
- कॉनराड इरविन ने Ruby इस्तेमाल करने वाले सभी लोगों के लिए, एक बहुत ही काम का सोर्स मैप जेम लिखा है
- eval नाम देने और displayName प्रॉपर्टी के बारे में ज़्यादा जानकारी
- सोर्स मैप बनाने के लिए, Closure Compilers का सोर्स देखें
- इसमें GWT सोर्स मैप के लिए सहायता के बारे में कुछ स्क्रीनशॉट और बातचीत शामिल है
सोर्स मैप, डेवलपर के टूल सेट में एक बहुत ही बेहतरीन सुविधा है. अपने वेब ऐप्लिकेशन को छोटा रखना और उसे आसानी से डीबग करना बहुत ज़रूरी है. यह नए डेवलपर के लिए भी एक बेहतरीन टूल है. इससे वे यह देख सकते हैं कि अनुभवी डेवलपर, छोटे किए गए कोड को पढ़े बिना अपने ऐप्लिकेशन कैसे बनाते और लिखते हैं.
अब इंतज़ार किस बात का? सभी प्रोजेक्ट के लिए, सोर्स मैप जनरेट करना शुरू करें!