𝗕𝗲𝘆𝗼𝗻𝗱 𝗠𝗶𝘀𝘀𝗶𝗻𝗴 𝗘𝘅𝗽𝗼𝗿𝘁𝘀: 𝗕𝘂𝗶𝗹𝗱𝗶𝗻𝗴 𝗮𝗻 𝗘𝗮𝗿𝗹𝘆 𝗚𝗮𝗿𝗯𝗮𝗴𝗲 𝗖𝗼𝗹𝗹𝗲𝗰𝘁𝗼𝗿
मी Webpack डॉक्युमेंटेशनमधील गहाळ लिंक्स सुधारण्यासाठी एक स्टँडर्ड प्लगइन वापरण्याचा प्रयत्न केला. ते अयशस्वी ठरले.
मोठ्या कोडबेसमध्ये प्लगइन समाविष्ट करणे सोपे काम नाही. ते एक आर्किटेक्चरल आव्हान बनले. मला Abstract Syntax Tree (AST) मॅनिप्युलेशन, मेमरी वापर आणि रिकर्सिव्ह लूप्स (recursive loops) व्यवस्थापित करावे लागले.
स्टँडर्ड प्लगइन्ससोबतची समस्या
उपाय शोधण्यासाठी मी तीन प्रयोग केले.
प्रयोग १: प्लगइनने १३५ प्रकार (types) शोधून काढले. मात्र, त्याने ते एका अंतर्गत मॉड्यूलमध्ये (internal module) टाकले. आमच्या टूलने त्यांच्यासाठी एक वेगळा फोल्डर तयार केला. आम्हाला ते मॅन्युअली सॉर्ट करावे लागले. डॉक्युमेंटेशनची रचना देखील चुकीची होती.
प्रयोग २: मी बाह्य प्रकार (external types) लपवण्यासाठी एक सेटिंग सुरू केली. यामुळे काही गोष्टींसाठी मदत झाली. यामुळे पेलोड (payload) कमी होऊन ६० Webpack प्रकार उरले. परंतु TypeDoc ने नेस्टेड डिपेंडन्सीज (nested dependencies) दुर्लक्षित केल्या. यामुळे अनेक प्रकार लपलेले राहिले, तरीही ते मेमरी वापरत होते.
प्रयोग ३: मी प्रकारांना त्यांच्या मूळ मॉड्यूल्सशी पुन्हा मॅप करण्याचा प्रयत्न केला. यामुळे रिकर्सिव्ह लूप तयार झाला. प्लगइनने नेस्टेड इंटरफेसेस (nested interfaces) काढणे सुरूच ठेवले, ज्यामुळे ६३० प्रकार तयार झाले. डॉक्युमेंटेशनमध्ये खूप गोंधळ (noise) निर्माण झाला. यामुळे युजर एक्सपिरियन्स (user experience) खराब झाला.
उपाय: अर्ली गार्बेज कलेक्शन (Early Garbage Collection)
मला अतिरिक्त गोंधळ न होता, योग्य मॉड्यूल्समध्ये ते प्रकार हवे होते. मी आउटपुट सुधारण्याचा प्रयत्न करणे थांबवले आणि प्रक्रिया (process) सुधारण्यावर लक्ष केंद्रित केले.
मी EVENT_RESOLVE_END नावाचा एक हुक (hook) वापरला. यामुळे मला रिझोल्यूशननंतर लगेच AST मध्ये हस्तक्षेप (intercept) करता आला. TypeDoc ने कॅटेगरी नियुक्त करण्यापूर्वी किंवा जास्त मेमरी वापरण्यापूर्वी मी हे केले.
माझे लॉजिक तीन पायऱ्यांवर आधारित होते:
- AST मध्ये अंतर्गत मॉड्यूल शोधा.
- कस्टम युटिलिटी वापरून प्रत्येक नोड तपासा.
- गोंधळ (noise) काढून टाका. मी ३०० अनावश्यक नोड्स त्वरित काढून टाकण्यासाठी
project.removeReflectionवापरले. यामुळे Node.js ला मेमरी मोकळी करण्यास मदत झाली. - महत्त्वाचे प्रकार हलवा. मी उर्वरित ३०० प्रकारांना रूट स्कोपमध्ये (root scope) विलीन केले.
निकाल: मी २४० महत्त्वाचे प्रकार वाचवले. ते आता दृश्यमान आहेत आणि योग्यरित्या रूट केले आहेत. मी तिसऱ्या प्रयोगातील रिकर्सिव्ह गोंधळ टाळला.
शिकलेले धडे
• AST ला लवकर हाताळा. अनावश्यक नोड्स काढून टाकल्यामुळे नंतर मेमरी वाया जाण्यापासून बचाव होतो. • हॅक्सऐवजी (hacks) हुक्स वापरा. कंपायलर लाइफसायकल समजून घेतल्यामुळे काम स्वच्छ आणि सुटसुटीत होते. • फीडबॅकमुळे आर्किटेक्चर सुधारते. मेंटेनरच्या (maintainer) रिव्ह्यूमुळे मला एक चांगली प्रणाली तयार करण्यास मदत झाली. • जास्त डेटा म्हणजे चांगले असे नाही. उत्तम इंजिनिअरिंग म्हणजे डेटा आणि वापरण्यायोग्यता (usability) यांच्यातील संतुलन राखणे.
गहाळ एक्सपोर्ट्सच्या पलीकडे: Webpack च्या TypeDoc AST साठी एक प्राथमिक Garbage Collector तयार करणे
तुम्ही कधी अशी परिस्थिती अनुभवली आहे का जिथे तुमच्या कोडमध्ये स्पष्टपणे परिभाषित केलेले असूनही तुमच्या डॉक्युमेंटेशनमध्ये काही एक्सपोर्ट्स (exports) गहाळ आहेत?
ही समस्या Webpack आणि TypeDoc वापरताना वारंवार उद्भवते. जेव्हा Webpack चे tree-shaking वैशिष्ट्य कोडमधील न वापरलेले भाग काढून टाकते, तेव्हा TypeDoc ला ते एक्सपोर्ट्स शोधण्यात अडचण येते.
समस्या: Tree-shaking आणि गहाळ एक्सपोर्ट्स
Webpack चे मुख्य काम कोड ऑप्टिमाइझ करणे आहे. यामध्ये 'tree-shaking' नावाचा एक महत्त्वाचा टप्पा असतो, जो न वापरलेले मॉड्यूल्स आणि एक्सपोर्ट्स काढून टाकतो जेणेकरून बंडलचा आकार कमी होईल.
परंतु, जेव्हा आपण TypeDoc वापरून डॉक्युमेंटेशन तयार करतो, तेव्हा आपल्याला अशा सर्व गोष्टींची आवश्यकता असते ज्या कोडमध्ये उपलब्ध आहेत, मग त्या सध्याच्या बिल्डमध्ये वापरल्या जात असल्या किंवा नसोत. Webpack च्या tree-shaking मुळे, हे एक्सपोर्ट्स 'dead code' म्हणून ओळखले जातात आणि काढून टाकले जातात, ज्यामुळे TypeDoc ला ते डॉक्युमेंटेशनमध्ये दाखवता येत नाहीत.
उपाय: AST-आधारित Garbage Collector
या समस्येचे निराकरण करण्यासाठी, आपण एक असा Garbage Collector तयार करू शकतो जो Webpack च्या प्रक्रियेच्या सुरुवातीलाच, AST (Abstract Syntax Tree) स्तरावर काम करेल.
याचा उद्देश Webpack ला हे सांगणे आहे की, "हे एक्सपोर्ट्स जरी सध्या वापरले जात नसले तरी, डॉक्युमेंटेशनसाठी ते आवश्यक आहेत, म्हणून त्यांना काढून टाकू नका."
हे कसे कार्य करते?
आमची पद्धत खालीलप्रमाणे आहे:
- AST पार्सिंग (Parsing): आपण TypeScript/JavaScript कोडचे AST मध्ये रूपांतर करतो.
- वापर शोधणे (Finding Usage): आपण संपूर्ण AST मध्ये फिरतो (traverse करतो) आणि शोधतो की कोणते एक्सपोर्ट्स वापरले जात आहेत.
- प्रभावी एक्सपोर्ट्सची ओळख (Identifying Effective Exports): आपण केवळ तेच एक्सपोर्ट्स 'live' मानतो जे डॉक्युमेंटेशनसाठी आवश्यक आहेत.
अंमलबजावणी (Implementation)
या प्रक्रियेसाठी, आपण AST वॉकर्स (walkers) वापरू शकतो जे प्रत्येक नोडची तपासणी करतात. जर एखादा नोड एखाद्या एक्सपोर्टचा संदर्भ देत असेल, तर आपण त्या एक्सपोर्टला 'used' म्हणून मार्क करतो.
// एक काल्पनिक उदाहरण
function markUsedExports(ast: Node) {
// AST मध्ये फिरून वापरलेले एक्सपोर्ट्स शोधणे
// ...
}
अशा प्रकारे, आपण Webpack च्या tree-shaking प्रक्रियेला प्रभावित न करता, TypeDoc साठी आवश्यक असलेले सर्व एक्सपोर्ट्स सुरक्षित ठेवू शकतो.
निष्कर्ष
Webpack आणि TypeDoc मधील ही विसंगती सोडवण्यासाठी AST-आधारित Garbage Collector हा एक प्रभावी मार्ग आहे. यामुळे तुमचे डॉक्युमेंटेशन अधिक अचूक आणि पूर्ण राहण्यास मदत होते.