परिचय
Rust में प्रोजेक्ट बढ़ने के साथ, यह सवाल उठता है: कोड को कैसे व्यवस्थित करें ताकि वह बनाए रखने योग्य, स्केलेबल और टीम के लिए सुविधाजनक रहे? एक लोकप्रिय दृष्टिकोण मोनोरेपॉजिटरी (monorepo) है। इस लेख में, हम समझेंगे कि मोनोरेपॉजिटरी क्या है, इसे Cargo workspace की मदद से कैसे व्यवस्थित करें, और व्यावहारिक उदाहरण देंगे। आप सीखेंगे कि कोड को कैसे संरचित करें, डिपेंडेंसी (dependencies) का प्रबंधन कैसे करें और सामान्य गलतियों से कैसे बचें।
मोनोरेपॉजिटरी क्या है और Rust में इसकी आवश्यकता क्यों है?
मोनोरेपॉजिटरी (या मोनोरेपो) एक एकल रिपॉजिटरी है जिसमें कई प्रोजेक्ट (क्रेट) या पैकेज होते हैं। मल्टी-रिपॉजिटरी के विपरीत, जहां प्रत्येक प्रोजेक्ट अलग रहता है, मोनोरेपॉजिटरी सब कुछ एक साथ जोड़ता है: लाइब्रेरी, बाइनरी, टेस्ट, कॉन्फ़िगरेशन और डॉक्यूमेंटेशन।
Rust के लिए मोनोरेपॉजिटरी के लाभ:
- डिपेंडेंसी का एकीकृत संस्करण — सभी क्रेट बाहरी पैकेज के समान संस्करण का उपयोग करते हैं, जिससे विरोध कम होता है।
- रीफैक्टरिंग को सरल बनाता है — एक लाइब्रेरी में किए गए बदलाव तुरंत सभी आश्रित क्रेट में दिखाई देते हैं।
- एंड-टू-एंड एकीकरण — पूरे प्रोजेक्ट के लिए टेस्ट और लिंटिंग आसानी से चलाई जा सकती है।
- केंद्रीकृत दस्तावेज़ीकरण — सभी दस्तावेज़ और CI/CD एक ही स्थान पर होते हैं।
हालांकि, मोनोरेपॉजिटरी सभी के लिए उपयुक्त नहीं है। छोटे प्रोजेक्ट या अलग-अलग डेवलपमेंट चक्र वाली टीमों के लिए मल्टीरेपो बेहतर है। लेकिन Rust इकोसिस्टम के लिए, जहां मॉड्यूलरिटी और कोड का पुन: उपयोग सामान्य है, मोनोरेपॉजिटरी एक शक्तिशाली उपकरण बन जाता है।
Cargo Workspace के साथ मोनोरेपॉजिटरी का संगठन
Cargo workspace तंत्र का समर्थन करता है — यह क्रेट का एक समूह है जो एक साथ बनते हैं और सामान्य Cargo.lock का उपयोग करते हैं। आइए मूल संरचना देखें।
Workspace बनाना
एक रूट डायरेक्टरी और Cargo.toml फ़ाइल बनाएं जिसमें [package] सेक्शन न हो, बल्कि [workspace] सेक्शन हो:
# रूट Cargo.toml[workspace]members = [ "core", "cli", "web",]अब core, cli, web सबडायरेक्टरी बनाएं। उनमें से प्रत्येक में पैकेज की सामान्य संरचना के साथ अपना स्वयं का Cargo.toml होना चाहिए। उदाहरण के लिए, core के लिए:
# core/Cargo.toml[package]name = "my_core"version = "0.1.0"edition = "2021"
[dependencies]serde = { version = "1.0", features = ["derive"] }cli और web के लिए, आप my_core पर निर्भरता निर्दिष्ट कर सकते हैं:
# cli/Cargo.toml[package]name = "my_cli"version = "0.1.0"edition = "2021"
[dependencies]my_core = { path = "../core" }clap = { version = "4.0", features = ["derive"] }अब जब आप रूट से cargo build चलाते हैं, तो सभी क्रेट बन जाएंगे, और Cargo.lock सामान्य होगा।
फ़ोल्डर और मॉड्यूल की संरचना
Rust के लिए अनुशंसित मोनोरेपॉजिटरी संरचना:
my_monorepo/├── Cargo.toml # workspace├── Cargo.lock├── core/ # सामान्य प्रकारों वाली लाइब्रेरी│ ├── Cargo.toml│ └── src/│ └── lib.rs├── cli/ # कंसोल एप्लिकेशन│ ├── Cargo.toml│ └── src/│ └── main.rs├── web/ # वेब सर्वर (उदाहरण के लिए, Actix पर)│ ├── Cargo.toml│ └── src/│ └── main.rs├── tests/ # इंटीग्रेशन टेस्ट (वैकल्पिक)│ └── integration_test.rs├── scripts/ # CI/CD के लिए स्क्रिप्ट└── README.mdप्रत्येक क्रेट के अंदर, Rust की मानक मॉड्यूलर संरचना का उपयोग करें। उदाहरण के लिए, core/src/lib.rs में:
// core/src/lib.rspub mod models;pub mod utils;और core/src/models.rs में:
// core/src/models.rsuse serde::{Serialize, Deserialize};
#[derive(Debug, Serialize, Deserialize)]pub struct
```