परिचय: Swift में मोनोरेपोजिटरी क्यों?
iOS और macOS के लिए डेवलपमेंट अक्सर एक दुविधा का सामना करता है: कोड को इस तरह कैसे व्यवस्थित करें कि वह स्केलेबल, पुन: प्रयोज्य और आसानी से बनाए रखने योग्य बना रहे? कई अलग-अलग रिपॉजिटरी (मल्टीरेपोजिटरी) का पारंपरिक दृष्टिकोण विखंडन, निर्भरताओं के दोहराव और बदलावों के समन्वय में कठिनाइयों की ओर ले जाता है। समाधान है मोनोरेपोजिटरी (monorepo)।
मोनोरेपोजिटरी एक एकल रिपॉजिटरी है जिसमें प्रोजेक्ट के सभी घटक शामिल होते हैं: एप्लिकेशन, लाइब्रेरी, बिल्ड टूल और कॉन्फ़िगरेशन। Swift इकोसिस्टम के लिए, यह दृष्टिकोण विशेष रूप से Swift Package Manager (SPM) के कारण प्रासंगिक है, जो संस्करण 5.3+ से लोकल पैकेज और मॉड्यूलर आर्किटेक्चर को बेहतरीन ढंग से सपोर्ट करता है।
इस लेख में, हम Swift प्रोजेक्ट्स के लिए मोनोरेपोजिटरी को व्यवस्थित करने का तरीका समझेंगे, संरचना, टूल्स (Tuist, XcodeGen) और कोड उदाहरणों के साथ सर्वोत्तम प्रथाओं पर विचार करेंगे।
1. Swift के लिए मोनोरेपोजिटरी के लाभ
कार्यान्वयन पर जाने से पहले, आइए मुख्य लाभों पर नज़र डालें:
- निर्भरताओं का एकीकृत संस्करण — सभी मॉड्यूल लाइब्रेरी के एक ही संस्करण का उपयोग करते हैं, जिससे विरोध समाप्त हो जाते हैं।
- परमाणु कमिट — एक पैकेज में API परिवर्तन तुरंत सभी आश्रित मॉड्यूल पर प्रतिबिंबित होता है, बिना रिपॉजिटरी के बीच सिंक्रनाइज़ेशन की आवश्यकता के।
- CI/CD का सरलीकरण — एक पाइपलाइन, एक कॉन्फ़िगरेशन, बिल्ड कैशिंग।
- कोड का पुन: उपयोग — सामान्य उपयोगिताएँ, मॉडल, नेटवर्किंग लेयर सभी टार्गेट्स (iOS, macOS, watchOS) के लिए आसानी से उपलब्ध हैं।
- कोड-रिव्यू — प्रोजेक्ट के विभिन्न हिस्सों में बदलाव एक ही PR में दिखाई देते हैं।
हालाँकि, नुकसान भी हैं: रिपॉजिटरी का आकार, क्लोनिंग का समय, एक सुविचारित संरचना की आवश्यकता। लेकिन मध्यम आकार और उससे बड़ी टीमों के लिए, मोनोरेपोजिटरी अक्सर सबसे अच्छा विकल्प साबित होता है।
2. Swift पर मोनोरेपोजिटरी की संरचना
एक सामान्य प्रोजेक्ट की संरचना पर विचार करें जिसमें iOS ऐप और macOS ऐप एक साझा लाइब्रेरी के साथ शामिल हैं:
MyProject/├── Apps/│ ├── iOSApp/│ │ ├── Sources/│ │ │ └── AppDelegate.swift│ │ ├── Resources/│ │ └── Package.swift│ └── macOSApp/│ ├── Sources/│ │ └── AppDelegate.swift│ ├── Resources/│ └── Package.swift├── Packages/│ ├── Core/│ │ ├── Sources/│ │ │ ├── Core.swift│ │ │ └── Extensions/│ │ ├── Tests/│ │ └── Package.swift│ ├── Networking/│ │ ├── Sources/│ │ │ └── NetworkManager.swift│ │ ├── Tests/│ │ └── Package.swift│ └── UIComponents/│ ├── Sources/│ │ └── CustomButton.swift│ ├── Tests/│ └── Package.swift├── Tools/│ └── Scripts/│ └── build.sh├── .github/│ └── workflows/│ └── ci.yml├── Package.swift (रूट)├── Tuist.swift (यदि Tuist का उपयोग कर रहे हैं)└── README.mdसंरचना का स्पष्टीकरण:
Apps/— अंतिम एप्लिकेशन वाली निर्देशिका। प्रत्येक एप्लिकेशन एक अलग Swift पैकेज है जोPackages/के पैकेजों पर निर्भर करता है।Packages/— सभी आंतरिक लाइब्रेरी और मॉड्यूल। प्रत्येक पैकेज का अपनाPackage.swiftहोता है और इसे स्वतंत्र रूप से परीक्षण किया जा सकता है।Tools/— बिल्ड स्क्रिप्ट, लिंटर्स, कोड जनरेशन।- रूट
Package.swift(या Tuist/XcodeGen कॉन्फ़िगरेशन) — वर्कस्पेस और पैकेजों के बीच संबंधों का वर्णन करता है।
2.1 रूट Package.swift का उदाहरण (SPM)
// swift-tools-version:5.9import PackageDescription
let package = Package( name: "MyProject", platforms: [ .iOS(.v16), .macOS(.v13) ], products: [ .library(name: "Core", targets: ["Core"]), .library(name: "Networking", targets: ["Networking"]), .library(name: "UICompon