سلسلة Swift Package Manager 03|المفاهيم الأساسية في Package.swift
الأمر الصعب حقًا هو فهم ما تعنيه المنتجات والأهداف والتبعيات في حدود المشروع.
عند فتح Package.swift لأول مرة، سيكون انطباعك الأول هو: الملف ليس طويلاً وبناء الجملة ليس معقدًا.
ولكن من السهل أن تشعر بالارتباك بمجرد بدء المشروع فعليًا، لأن الصعوبة لا تكمن على الإطلاق في “هل يبدو بناء الجملة مثل Swift”، ولكن في حقيقة أن العديد من المفاهيم الأساسية فيه تتوافق فعليًا مع بنية المشروع، وليس عناصر التكوين العادية.
إذا كنت تفكر في الأمر على أنه “قائمة لملء بعض الحقول”، فستشعر غالبًا أنك تعرف كل كلمة، ولكن من السهل أن يصبح الأمر مربكًا عند تغييرها. ما يجب فهمه حقًا هو الأسئلة التي تجيب عليها هذه المفاهيم.
الشيء الأكثر أهمية هو التقاط هذه الأدوار الأساسية أولاً:
- الحزمة
- المنتجات
- التبعيات
- الأهداف
1. يصف Package.swift علاقات الوحدات
هذه هي الخطوة الأولى لفهم ذلك.
من المواقف الشائعة أنك تفكر في الأمر دون وعي على النحو التالي:
-ملف تكوين المشروع
- يعتمد على ملفات التثبيت
- أو “Podspec for Swift”
ولكن من منظور هندسي، فإن Package.swift يشبه إلى حد كبير مواصفات علاقة الوحدة النمطية.
إنها تخبر سلسلة الأدوات:
- ماذا تقدم هذه الحزمة للعالم الخارجي؟
- ما هي الباقات الخارجية التي يعتمد عليها؟
- ما هي الأهداف التي تتألف منها داخليا؟
- مدى ارتباط هذه الأهداف ببعضها البعض
لذا فهو يركز على “كيفية تنظيم هذا الكود في وحدات واستخدامها من قبل الآخرين.”
2. إجابات products: ما هي الإمكانيات التي تريد هذه الحزمة تقديمها للعالم الخارجي؟
هذه هي النقطة الأكثر سهولة التي يتم التغاضي عنها عند التعامل في البداية مع هذا النوع من المشكلات.
target هي وحدة البناء الداخلية، وproduct هي النتيجة القابلة للاستهلاك خارجيًا.
بمعنى آخر السؤال الذي أجاب عليه product هو:
ما هو الهدف الذي تهدف هذه الحزمة في النهاية إلى كشفه لمستخدميها؟
هناك إشارة تصميم مهمة جدًا وراء ذلك.
إذا لم تكن لديك أي فكرة عن product، فمن السهل الخلط بين البنية الداخلية للحزمة واستخدامها الخارجي.
وبطبيعة الحال، يمكن أن تكون هناك أهداف متعددة داخل الحزمة، ولكن الخارج لا يحتاج بالضرورة إلى معرفة كل هذه الانقسامات الداخلية.
لذا فإن product يقوم بشكل أساسي بتغليف الواجهة الخارجية.
إذا فهمت الأمر من هذا المنظور، فسوف تفكر بشكل طبيعي أكثر:
- ما هي الأهداف الداخلية تفاصيل التنفيذ
- ما هي القدرات التي تحتاج حقًا إلى الكشف عنها؟
- ما هو المستوى الذي يجب أن يراه المعالون الخارجيون؟
3. إجابات dependencies: ما هي القدرات التي تستعيرها هذه الحزمة من العالم الخارجي؟
عندما رأيت هذا الموقف dependencies، فكرت للتو في “تثبيت مكتبة خارجية”.
لكن من الناحية الهندسية فإن أهميتها الأهم هي:
خارج حدود هذه الوحدة، ما هو العالم الخارجي الذي تعتمد عليه؟
وهذا سوف يؤثر بشكل مباشر على:
- هل الوحدة خفيفة بما فيه الكفاية؟
- هل تجميعها مكلف؟
- هل من السهل إعادة استخدامها في المستقبل؟
- هل سيربط المشروع المضيف أيضًا ببعض التبعيات الخارجية؟
إذا كانت الوحدة تحتوي على عدد كبير جدًا من التبعيات الخارجية، فغالبًا ما يتسبب ذلك في مشكلتين:
- لم يعد خفيف الوزن
- كما أن حدودها بدأت تصبح غير واضحة
لذلك عند النظر إلى dependencies، لا تفكر فقط في “هل يمكن تثبيته”، ولكن فكر أيضًا في “لماذا تحتاج هذه الوحدة إلى الاعتماد على هذه الأشياء”.
4. إجابات targets: كيف ينبغي تنظيم وتجميع التعليمات البرمجية الداخلية؟
هذا هو الجزء من Package.swift الذي يُنظر إليه بسهولة على أنه “تعيين المجلدات”، ولكنه في الواقع أكثر من ذلك بكثير.
target يتوافق حقًا مع:
- مجموعة من الأكواد التي تم تجميعها معًا
- وحدة تبعية صريحة
- حدود الوحدة الداخلية
عندما تحدد الهدف، فإنك تقرر:
- ما هي الرموز التي يجب أن تتطور معًا؟
- ما هي التطبيقات التي ينبغي وضعها في نفس وحدة الترجمة
- ما هي الاختبارات التي يجب أن تتوافق مع هذه الحدود
لذا فإن الهدف هو أحد أصغر الوحدات الحاملة للوحدات الداخلية.
إذا قمت بتقسيم الهدف إلى أجزاء كثيرة جدًا، فسيصبح المشروع أثقل. إذا كان الهدف كبيرًا جدًا، فستكون الحدود غير واضحة. يوضح هذا أيضًا أن Package.swift يبدو مجرد تكوين، ولكنه يحمل في الواقع الكثير من الأحكام المعمارية.
5. الخلط بين product وtarget
لأنه في الحزم البسيطة، غالبًا ما تتوافق مع واحد لواحد.
على سبيل المثال:
- هدف
- منتج مكتبة
في هذا الوقت، من السهل أن نعتقد خطأً أن المفهومين متشابهان. ولكن بمجرد أن يصبح المشروع أكثر تعقيدًا، ستجد:
- يمكن أن تحتوي الحزمة على أهداف متعددة
- تعدد الأهداف يمكن أن يخدم منتج واحد
- بعض الأهداف هي مجرد تطبيقات داخلية ولا ينبغي الكشف عنها بشكل مباشر
لذلك تجربتي هي: ** فهم الهدف باعتباره الهيكل الداخلي والمنتج باعتباره المنفذ الخارجي. **
بهذه الطريقة سيصبح التفكير أكثر وضوحًا في الحال.
6. اختبار الهدف مهم جدًا أيضًا
عندما ترى Package.swift لأول مرة، ستعتبر هدف الاختبار بمثابة تكوين ملحق.
ولكن من منظور التفكير المعياري، فهو في الواقع مهم جدًا.
نظرًا لأن قيمة الوحدة لا تستحق الوجود المستقل، فإنها تنعكس أيضًا إلى حد كبير في:
- هل يمكن اختباره بشكل مستقل
- ما إذا كانت حدود تبعيتها واضحة بما فيه الكفاية
- ما إذا كان بإمكانه التحقق من السلوك الأساسي دون الاعتماد على التطبيق المضيف
إذا كان على الوحدة أن تعتمد على نصف المشروع المضيف في كل اختبار، فبالرغم من أنها حزمة في الاسم، إلا أن الحدود قد لا تكون مستقلة في الواقع.
7. ترتيب قراءة أكثر عملية
إذا قمت بفتح Package.swift لمشروع غير مألوف للمرة الأولى، فعادةً ما أنظر إليه بهذا الترتيب:
1.products
دعونا نلقي نظرة أولاً على ما يعرضه للعالم الخارجي.
2.dependencies
دعونا ننظر إلى ما اقترضته من العالم الخارجي
3.targets
وأخيرا، دعونا نرى كيف يتم تفكيك الداخل.
فوائد هذا التسلسل هي: انظر إلى الحدود أولاً، ثم انظر إلى الداخل، بدلاً من التورط في تفاصيل التنفيذ.
8. الخلاصة: لا تكمن صعوبة Package.swift في بناء الجملة، ولكن في أنها تصف حدود المشروع فعليًا.
ولكي أختصر الأمر أقول:
Package.swiftالشيء الأكثر أهمية هو ما إذا كان بإمكانك فهم العلاقة الحدودية وراءproductوdependencyوtarget.
بمجرد فهم هذا الملف من هذا المنظور، لم يعد مجرد تكوين، بل تعبير مكثف عن تصميم الوحدة.
What to read next
Want more posts about Swift Package Manager?
Posts in the same category are usually the best next step for reading more on this topic.
View same categoryWant to keep following #Swift?
Tags are useful for related tools, specific problems, and similar troubleshooting notes.
View same tagWant to explore another direction?
If you are not sure what to read next, return to the homepage and start from categories, topics, or latest updates.
Back home