लीगेसी जावास्क्रिप्ट कोड का रीफैक्टरिंग: उन्नत स्तर
\n\nविरासत (लीगेसी) कोड के साथ काम करना किसी भी डेवलपर के लिए एक अपरिहार्य वास्तविकता है, खासकर Node.js के क्षेत्र में। अक्सर ऐसा कोड ग्लोबल वेरिएबल्स, नेस्टेड callback, सैकड़ों पंक्तियों लंबे फंक्शन और मॉड्यूलर संरचना की पूर्ण अनुपस्थिति का "दलदल" होता है। यहाँ सरल रीफैक्टरिंग विधियाँ काम नहीं करतीं: एक व्यवस्थित दृष्टिकोण और उन्नत तकनीकों का ज्ञान आवश्यक है। इस लेख में, हम उन रणनीतियों पर चर्चा करेंगे जो प्रोडक्शन को रोके बिना अराजकता को एक रखरखाव योग्य आर्किटेक्चर में बदलने में मदद करेंगी।
\n\n1. निर्भरताओं का विश्लेषण और मैपिंग
\n\nकोड बदलने से पहले, उसे समझना होगा। लीगेसी प्रोजेक्ट्स में डॉक्यूमेंटेशन अक्सर अनुपस्थित या पुरानी होती है। पहला कदम निर्भरता का नक्शा बनाना है।
\n\nउपकरण:
\n- \n
- Madge — मॉड्यूल्स के बीच निर्भरताओं को विज़ुअलाइज़ करने की उपयोगिता। यह चक्रीय निर्भरताएँ और "मृत" फ़ाइलें दिखाएगा। \n
- प्लगइन्स के साथ ESLint — अप्रयुक्त वेरिएबल्स, फंक्शन और इम्पोर्ट्स की पहचान करने में मदद करेगा। \n
- पृथक वातावरण में डिप्लॉय — टेस्ट चलाएँ (यदि नहीं हैं, तो कम से कम smoke-टेस्ट लिखें) और रिकॉर्ड करें कि कौन से मॉड्यूल लोड होते हैं। \n
उदाहरण: मान लीजिए हमारे पास एक फ़ाइल legacy.js है जिसमें 2000 पंक्तियाँ हैं और यह एक ग्लोबल वेरिएबल config का उपयोग करती है।
// legacy.js (रीफैक्टरिंग से पहले)\nvar config = {\n apiUrl: 'https://api.example.com',\n timeout: 5000\n};\n\nfunction fetchData(callback) {\n // नेस्टेड if और try/catch के साथ 50 पंक्तियों का तर्क\n // ग्लोबल config का उपयोग करता है\n if (config.timeout > 0) {\n // ...\n }\n callback(null, data);\n}\n\n\nकार्रवाई: Madge का उपयोग करके हम देखते हैं कि legacy.js को 15 अन्य फ़ाइलों में इम्पोर्ट किया गया है। यह एक "दिव्य वस्तु" है। हमारा कार्य इसे परमाणु मॉड्यूल्स में विभाजित करना है।
2. "Strangler Fig" (फिगस दमघोंटू) रणनीति
\n\nयह पैटर्न सिस्टम को रोके बिना रीफैक्टरिंग के लिए आदर्श है। सार: हम एक साथ सब कुछ फिर से नहीं लिखते, बल्कि धीरे-धीरे पुराने सिस्टम के हिस्सों को नए से बदलते हैं, जब तक कि पुराना खुद ही खत्म न हो जाए।
\n\nNode.js में कार्यान्वयन:
\n- \n
- स्वच्छ आर्किटेक्चर के साथ एक नया मॉड्यूल बनाएँ। \n
- एक प्रॉक्सी-लेयर (या फ़ेसेड) लिखें जो कॉल को पुराने या नए मॉड्यूल पर रीडायरेक्ट करे। \n
- धीरे-धीरे उपभोक्ताओं को नए मॉड्यूल पर स्विच करें। \n
उदाहरण: पुरानी callback-शैली को Promise/async/await से बदलना।
\n\n// पुराना API (callback-आधारित)\nfunction getUser(id, callback) {\n // लीगेसी कोड\n callback(null, { id: id, name: 'John' });\n}\n\n// नया API (Promise-आधारित)\nasync function getUserAsync(id) {\n // async/await के साथ नया कार्यान्वयन\n const user = await database.findUser(id);\n return user;\n}\n\n// प्रॉक्सी-फ़ेसेड\nasync function getUserFacade(id) {\n if (USE_NEW_IMPLEMENTATION) {\n return getUserAsync(id);\n } else {\n return new Promise((resolve, reject) => {\n getUser(id, (err, user) => {\n if (err) reject(err);\n else resolve(user);\n });\n });\n }\n}\n\n\nफ़्लैग USE_NEW_IMPLEMENTATION को कॉन्फ़िगरेशन या feature toggle में रखा जा सकता है। यह उपयोगकर्ताओं के एक हिस्से के लिए नया कोड चालू करने (canary release) या डिप्लॉय के बिना बदलावों को वापस लेने की अनुमति देता है।
3. मॉड्यूलरीकरण और साइड इफेक्ट्स का अलगाव
\n\nलीगेसी कोड अक्सर छिपे हुए साइड इफेक्ट्स से ग्रस्त होता है: फंक्शन ग्लोबल स्टेट बदलता है, फ़ाइल में लिखता है या बाहरी API को कॉल करता है, बिना परिणाम लौटाए। ऐसे फंक्शन का रीफैक्टरिंग शुद्ध तर्क को अलग करना है।
\n\nतकनीक: "फंक्शन निकालना" (Extract Function) और उसके बाद डिपेंडेंसी इंजेक्शन (Dependency Injection) लागू करना।
\n\nसमस्याग्रस्त कोड:
\n\n