परिचय: Legacy कोड – सज़ा नहीं, एक चुनौती
\n\nहर डेवलपर को कभी न कभी legacy कोड से जूझना पड़ता है – यानी पुराना, खराब डॉक्यूमेंटेड और अक्सर बिना टेस्ट वाला JavaScript (Node.js) कोड। ऐसे कोड के साथ काम करना डरावना और निराशाजनक हो सकता है, लेकिन यह प्रोफेशनल ग्रोथ का एक अहम हिस्सा है। Legacy कोड रिफैक्टरिंग का मतलब सिर्फ कोड को दोबारा लिखना नहीं है, बल्कि बाहरी व्यवहार को बदले बिना आंतरिक संरचना को बेहतर बनाने की एक व्यवस्थित प्रक्रिया है।
\n\nइस लेख में, हम JavaScript में पुराने कोड को रिफैक्टर करने का एक स्टेप-बाय-स्टेप तरीका सीखेंगे, जिसमें रणनीतियाँ, टूल्स और Node.js के लिए ठोस उदाहरण शामिल हैं। आप जानेंगे कि कैसे "बुरे सपने" जैसे कोड को एक मेंटेन करने योग्य, स्केलेबल और आधुनिक कोडबेस में बदला जा सकता है।
\n\n1. विश्लेषण और तैयारी: रिफैक्टरिंग की शुरुआत कहाँ से करें?
\n\n1.1. मौजूदा कोड का ऑडिट
\n\nकुछ भी बदलने से पहले, मौजूदा सिस्टम को पूरी तरह समझना ज़रूरी है। इन तरीकों का उपयोग करें:
\n\n- \n
- स्टैटिक एनालिसिस: ESLint और उसके प्लगइन्स (eslint-plugin-import, eslint-plugin-security) से समस्याग्रस्त पैटर्न पकड़ें। \n
- "रेड फ्लैग्स" खोजें: 50 लाइन से लंबे फंक्शन, ग्लोबल वेरिएबल्स, callback hell, और मॉड्यूलरिटी की कमी। \n
- मौजूदा व्यवहार का दस्तावेज़ीकरण: मुख्य फंक्शन के सभी इनपुट और आउटपुट नोट करें। \n
// उदाहरण: ESLint से "खराब" पैटर्न खोजना\n// npm install eslint @eslint/js eslint-plugin-security --save-dev\n\n// eslint.config.js\nimport js from "@eslint/js";\nimport security from "eslint-plugin-security";\n\nexport default [\n js.configs.recommended,\n security.configs.recommended,\n {\n rules: {\n "no-var": "error",\n "prefer-const": "error",\n "max-lines-per-function": ["warn", 40],\n },\n },\n];\n\n\n1.2. सुरक्षा जाल बनाएँ: टेस्ट
\n\nरिफैक्टरिंग का नियम #1: बिना टेस्ट के कभी भी कोड रिफैक्टर न करें। Node.js के लिए Jest या Mocha का उपयोग करें। इंटीग्रेशन टेस्ट से शुरुआत करें जो ऐप के मुख्य सीनारियो को चेक करते हैं।
\n\n// उदाहरण: legacy फंक्शन के लिए टेस्ट\n// legacy.js\nfunction processOrder(orderData) {\n // ... 150 लाइनों का उलझा हुआ कोड\n return result;\n}\n\n// processOrder.test.js\nconst processOrder = require('./legacy');\n\ndescribe('processOrder', () => {\n it('सामान्य ऑर्डर को प्रोसेस करना चाहिए', () => {\n const input = { id: 1, items: ['book', 'pen'], total: 25 };\n const result = processOrder(input);\n expect(result.status).toBe('completed');\n expect(result.total).toBe(25);\n });\n\n it('खाली ऑर्डर पर एरर देनी चाहिए', () => {\n expect(() => processOrder({})).toThrow('Invalid order');\n });\n});\n\n\n2. रिफैक्टरिंग की रणनीतियाँ: अराजकता से व्यवस्था तक
\n\n2.1. "Strangler Fig" (गला घोंटने वाला फिकस) रणनीति
\n\nयह तरीका बड़े Node.js प्रोजेक्ट्स के लिए बहुत कारगर है। इसमें आप पूरे ऐप को रोके बिना, legacy सिस्टम के हिस्सों को धीरे-धीरे नए मॉड्यूल से बदलते हैं।
\n\n// उदाहरण: पुराने HTTP क्लाइंट को नए से बदलना\n// पुराना कोड (legacy)\nconst http = require('http');\n\nfunction fetchUserData(userId) {\n return new Promise((resolve, reject) => {\n http.get(`http://api.example.com/users/${userId}`, (res) => {\n let data = '';\n res.on('data', chunk => data += chunk);\n res.on('end', () => resolve(JSON.parse(data)));\n }).on('error', reject);\n });\n}\n\n// नया मॉड्यूल (आधुनिक)\nconst axios = require('axios');\n\nasync function fetchUserDataModern(userId) {\n const response = await axios.get(`https://api.example.com/users/${userId}`);\n return response.data;\n}\n\n// मध्यवर्ती परत (फ़ेसेड)\nasync function getUserData(userId) {\n // पहले नया API आज़माएँ, एरर होने पर पुराने पर वापस जाएँ\n try {\n return await fetchUserDataModern(userId);\n } catch (error) {\n console.warn('Falling back to legacy API