SDP के साथ सर्कुलर डिपेंडेंसीज़ (Circular Dependencies) को रोकें

सर्कुलर डिपेंडेंसीज़ खामोश कातिल हैं। ये बिल्ड एरर (build errors) पैदा नहीं करतीं। ये इम्पोर्ट (import) के समय रनटाइम एक्सेप्शन (runtime exceptions) भी नहीं देतीं। इसके बजाय, ये सूक्ष्म 'undefined' वैल्यूज़ का कारण बनती हैं जो हफ्तों बाद प्रोडक्शन में दिखाई देती हैं।

एक साइकिल तब बनती है जब मॉड्यूल A, B से इम्पोर्ट करता है, और B वापस A से इम्पोर्ट करता है।

JavaScript इन इम्पोर्ट्स को खामोशी से हल कर देता है। यदि मॉड्यूल B द्वारा अनुरोध किए जाने पर मॉड्यूल A अभी भी लोड हो रहा है, तो JavaScript एक खाली ऑब्जेक्ट (empty object) लौटा देता है। आपका कोड बाद में फेल हो जाता है, और स्टैक ट्रेस (stack trace) गलत जगह की ओर इशारा करता है।

आप इसे dependency-cruiser के साथ ठीक कर सकते हैं। यह टूल आपकी फाइलों को स्कैन करता है और आपके डिपेंडेंसी ग्राफ (dependency graph) को मैप करता है। यह TypeScript और monorepos के साथ काम करता है।

इसे कैसे सेटअप करें:

  • इसे अपनी dev dependencies में जोड़ें: yarn add -D dependency-cruiser
  • अपने package.json में एक स्क्रिप्ट जोड़ें: "depcruise": "depcruise packages --config .dependency-cruiser.js"
  • साइकिल को पकड़ने के लिए एक .dependency-cruiser.js फ़ाइल बनाएँ।

लेकिन साइकिल को ढूँढना तो केवल आधी लड़ाई है। आपको उन्हें बनने से रोकना होगा।

Stable Dependencies Principle (SDP) का उपयोग करें। यह नियम कहता है कि आपको स्थिरता (stability) की दिशा में निर्भर होना चाहिए।

स्थिरता (Stability) एक संरचनात्मक गुण (structural property) है। एक मॉड्यूल तब स्थिर होता है जब कई अन्य मॉड्यूल उस पर निर्भर होते हैं। यदि आप एक स्थिर मॉड्यूल को बदलते हैं, तो आप कई लोगों को प्रभावित करते हैं। यही लागत (cost) इसे स्थिर बनाती है।

Instability फॉर्मूला का उपयोग करें: I = Fan-Out / (Fan-In + Fan-Out)

• I = 0 का अर्थ है कि मॉड्यूल अधिकतम रूप से स्थिर (maximally stable) है। सब कुछ उस पर निर्भर है, और वह किसी पर निर्भर नहीं है। • I = 1 का अर्थ है कि मॉड्यूल अधिकतम रूप से अस्थिर (maximally unstable) है। यह कई चीजों पर निर्भर है, और कोई भी इस पर निर्भर नहीं है।

नियम: एक मॉड्यूल का इंस्टेबिलिटी स्कोर (instability score) उसके द्वारा इम्पोर्ट किए गए प्रत्येक मॉड्यूल के स्कोर से अधिक होना चाहिए। आपके तीर (arrows) कम इंस्टेबिलिटी की ओर इशारा करने चाहिए।

आपके लो-लेवल utils (I ≈ 0) को कभी भी आपके हाई-लेवल pages (I ≈ 1) से इम्पोर्ट नहीं करना चाहिए।

आप dependency-cruiser के साथ इस सिद्धांत को एक स्वचालित नियम (automated rule) में बदल सकते हैं। केवल साइकिल की जाँच करने के बजाय, दिशा की जाँच करें:

  • utils को features से इम्पोर्ट करने से रोकें।
  • features को pages से इम्पोर्ट करने से रोकें।

यह उन संरचनात्मक स्थितियों को रोकता है जो साइकिल बनाती हैं। आप बग्स (bugs) पर प्रतिक्रिया देना बंद कर देते हैं और उन्हें रोकना शुरू कर देते हैं।

स्रोत: https://dev.to/wojciech_kot_b82f5d7cbfc6/stop-circular-dependencies-before-they-stop-you-dependency-cruiser-the-stable-dependencies-34ho