आइडेंटिफ़ायर टकराव से बचना
जब कई VM-ऑब्फ़स्केटेड फ़ाइलें एक ही बंडल में पहुँचती हैं, तो वे एक ही टॉप-लेवल आइडेंटिफ़ायर डिक्लेयर कर सकती हैं और पार्स के समय पेज को क्रैश कर सकती हैं। यहाँ बताया गया है कि ऐसा क्यों होता है और इसे कैसे ठीक करें।
लक्षण
आपका बिल्ड ठीक चलता है, लेकिन ऐप शुरू होने से पहले ही ब्राउज़र पार्स के समय एरर फेंकता है:
यह देखने के लिए कि एरर वाला नाम कितने चंक में डिक्लेयर है, उन फ़ाइलों को गिनें जिनमें उसका डिक्लेरेशन है:
-l हर मेल खाने वाली फ़ाइल को एक बार सूचीबद्ध करता है और -w केवल पूरे शब्दों से मेल खाता है, इसलिए vmdX नहीं गिना जाता। var को छोड़ दिया गया है, क्योंकि var डिक्लेरेशन दोहराना अपने आप में एरर नहीं है। 1 से बड़े नतीजे
का मतलब है कि नाम एक से ज़्यादा चंक में डिक्लेयर है। vmd को अपने एरर संदेश वाले नाम से बदलें।
आइडेंटिफ़ायर टकराव तभी मायने रखता है जब डिक्लेरेशन एक ही स्कोप में हों। अलग-अलग मॉड्यूल या क्लोज़र में दोहराया गया एक ही नाम टकराव का सबूत नहीं है; ऊपर दिखाई गई पार्स एरर है।
ऐसा क्यों होता है
VM प्रीसेट mangled-shuffled identifier-names generator का उपयोग करते हैं। यह एक छोटी वर्णमाला पर फेंटे हुए क्रम में
चलता है, और VM ऑब्फ़स्केशन में नाम बदले गए हर ग्लोबल को vm प्रीफ़िक्स मिलता है (डिफ़ॉल्ट identifiersPrefix)। फेंटा
हुआ क्रम प्रति प्रोसेस कैश होता है, इसलिए एक ही प्रोसेस में, या एक ही निश्चित seed के साथ ऑब्फ़स्केट की गई फ़ाइलें उसी
क्रम से नाम लेती हैं - हर फ़ाइल का पहला ग्लोबल एक ही नाम पाता है, दूसरा एक और साझा नाम, और इसी तरह आगे।
हर फ़ाइल स्वतंत्र रूप से ऑब्फ़स्केट होती है और generator हर फ़ाइल के लिए अपने क्रम की शुरुआत से दोबारा चलता है। जब दो
फ़ाइलें एक ही स्कोप में पहुँचती हैं, तो नाम टकरा जाते हैं। दो टॉप-लेवल const vmd = … डिक्लेरेशन एक ही स्कोप में आ जाते हैं
और पार्सर दूसरे को अस्वीकार कर देता है।
जो विकल्प ज़्यादा टॉप-लेवल आइडेंटिफ़ायर जोड़ते हैं, वे दो फ़ाइलों के एक ही जनरेट किए गए नाम तक पहुँचने की संभावना बढ़ाते हैं।
vmWrapTopLevelInitializers उनमें से एक है, और हर VM प्रीसेट इसे पहले से चालू करता है; vmDynamicOpcodes या
vmBytecodeEncoding जैसे विकल्प और भी जोड़ते हैं।
समाधान
बेहतर है कि पहले बंडल करें, फिर बंडल को एक बार ऑब्फ़स्केट करें। अगर आप अलग-अलग ऑब्फ़स्केट करते ही हैं और स्क्रिप्ट्स एक ग्लोबल स्कोप साझा करती हैं, तो इनमें से कोई एक चुनें:
randomIdentifiersPrefixचालू करें (अनुशंसित)हर ऑब्फ़स्केशन रन को एक रैंडम प्रीफ़िक्स मिलता है, जो हर ग्लोबल आइडेंटिफ़ायर के आगे जोड़ा जाता है (VM ऑब्फ़स्केशन में यह डिफ़ॉल्ट
vmप्रीफ़िक्स की जगह लेता है)। अलग-अलग फ़ाइलों के नाम अब एक नेमस्पेस साझा नहीं करते, इसलिए प्रीफ़िक्स को हाथ से तालमेल बिठाए बिना टकराव खत्म हो जाते हैं।हर फ़ाइल के लिए अलग
identifiersPrefixसेट करेंहर फ़ाइल को ऑब्फ़स्केट करते समय हाथ से अलग प्रीफ़िक्स दें (उदाहरण के लिए एक के लिए
identifiersPrefix: 'auth_', दूसरी के लिएcheckout_)। यह कारगर है, लेकिन बहुत सारी फ़ाइलें होने पर इसमें गलती की गुंजाइश रहती है, इसलिए ऊपर वाला रैंडम विकल्प बेहतर है।identifierNamesGeneratorकोhexadecimalपर बदलेंHexadecimal नामों का कीस्पेस कहीं बड़ा होता है, इसलिए दो फ़ाइलों के एक ही आइडेंटिफ़ायर बनाने की संभावना बहुत कम होती है, लेकिन अनोखेपन की गारंटी नहीं है। समझौता: आइडेंटिफ़ायर
mangled-shuffledआउटपुट से लंबे होते हैं, इसलिए बंडल थोड़ा बड़ा होता है।मल्टी-फ़ाइल बैच UI इस्तेमाल करें, या अपना बंडलर प्लगइन जाँचें
डैशबोर्ड मल्टी-फ़ाइल बैच ऑब्फ़स्केशन में हर फ़ाइल के लिए अलग प्रीफ़िक्स जोड़ता है, जो पेड प्लान पर उपलब्ध है। अगर आप बंडलर प्लगइन इस्तेमाल करते हैं, तो यह मानने के बजाय कि वह भी ऐसा ही करता है, उसका व्यवहार जाँचें। अगर आप npm API से ऑब्फ़स्केशन हाथ से जोड़ रहे हैं, तो प्रीफ़िक्स आपको खुद चालू करना होगा।
समाधान की पुष्टि करने के लिए, संयुक्त एप्लिकेशन को फिर से बिल्ड और लोड करें और पक्का करें कि SyntaxError चली गई है। पुराने
एरर संदेश वाला नाम अब एक से ज़्यादा चंक में डिक्लेयर नहीं होना चाहिए; प्रीफ़िक्स हर जनरेट किए गए नाम को बदल देता है, इसलिए
ऊपर वाला grep केवल उसी खास नाम के बारे में बताता है, नए नामों के बारे में नहीं।
संबंधित विकल्प
randomIdentifiersPrefix- हर बिल्ड के लिए रैंडम प्रीफ़िक्स (अनुशंसित)identifiersPrefix- स्पष्ट प्रीफ़िक्स स्ट्रिंगidentifierNamesGenerator- नामों का स्वरूप (mangled,hexadecimal, …)
