
كيف نقوم بإدارة المكتبات اللازمة لتطوير التطبيقات
بدايةً نعرّف المكتبة بأنها مجموعة متكاملة (بحد ذاتها) من الخوارزميات وأنواع البيانات، بإمكانها القيام بمجموعة مختلفة من العمليات بغض النظر عن نوع التطبيق الذي نقوم بطويره، بحيث يمكن اعتبارها قابلة لاعادة الاستخدام Reusable.
لو أردنا التعامل مع نظام الملفات ضمن نظام التشغيل، فإننا نقوم باستدعاء مكتبة Input/Output الخاصة بالتعامل مع الملفات، وسنجد داخلها العديد من الخوارزميات الخاصة بإنشاء الملفات والمجلدات والنسخ وباقي المهام الاخرى.
الآن في كل تطبيق نقوم بكتابته/تطويره قد نحتاج للعديد من المكتبات لاستخدامها في تنفيذ مهام مختلفة، وسواء كانت هذه المكتبات هي مكتبات خاصة بنا أو تابعة لنفس إطار العمل، أو حتى من طرف ثالث Third Party، إلا أنه وبمجرد إضافة هذه المكتبات إلى مشروعنا، يصبح بإمكاننا استخدام الخوارزميات وانواع البيانات المتوفرة داخلها.
دراسة الحالة
تكمن المشكلة الاساسية في إدارة هذه المكتبات، بأننا غالبا نتبع الطريقة التقليدية، وهي نسخ المكتبة (الملف) الى مسار مشروعنا، ثم نقوم باستدعاءها داخل الكود الخاص بنا.
المشكلة 1
نحن بحاجة دائما لنسخة من هذه المكتبة متوفرة لدينا حتى نستطيع استخدامها، او سنضطر للبحث عنها على الانترنت!
المشكلة 2
لو قمنا بنسخ المشروع إلى جهاز آخر او حتى قمنا بإنشاء مشروع جديد، فإننا بحاجة للتأكد من ان المكتبة تم نسخها ايضا مع المشروع، تظهر هذه المشكلة بشكل واضح في حال استخدمنا Version Control System مثل Git او GitHub، حيث انه غالبا لا يقوم بنسخ هذه المكتبات، بالتالي سنضطر مرة اخرى للبحث عن هذه المكتبات واعادة ربطها بالمشروع.
المشكلة 3
ماذا لو كان المشروع الذي بين ايدينا يحوي على مكتبة من اصدار مختلف عن اصدار المكتبة المتوفرة لدينا، بالتأكيد سنقوم بالبحث عن الاصدار الجديد او القديم حتى، وتثبيته مرة اخرى على مشروعنا.
المشكلة 4
ماذا لو تم اصدار نسخة جديدة من المكتبة التي نعمل عليها، بحيث تحوي على مجموعة تحديثات جديدة، بالتأكيد نحتاج ألية لمعرفة ان هناك اصدارات جديدة؟ وفي حال عرفنا ان هناك اصدار جديد، سنكون بمواجهة المشكلة 3
المشكلة 5
ماذا لو كان لديك بدل المكتبة الواحدة عشرات المكتبات! بالتاكيد اصبحت عملية ادارة ومتابعة المكتبات عملية مستقلة بحد ذاتها، ومرهقة ايضاً.
لذلك وبما أن عالم التكنولوجيا عالم سريع التطور ومفتوح للجميع، ظهر لدينا مفهوم Package Management، لتولي هذه المهمة بدلاً عنا، بحيث يكون تركيزنا الأساسي على كتابة وجودة الكود.
Package Management
هي آلية لتنظيم المكتبات (حل جميع المشاكل السابقة بالنيابة عنا). يقوم بهذه المهمة (النبيلة) سوفت وير خاص اسمه Package Manager
تقريبا جميع اللغات والتقنيات، اصبحت تملك Package Manager خاص بها، متكامل مع بيئة العمل، بحيث يقوم بالاجراءات اللازمة داخل المشروع بالنيابة عنك.
لنأخذ اطار العمل الدوت نت كمثال، ونرى كيف تتم عملية ادارة المكتبات ضمنه.
اطار العمل NET. كمثال
يحوي اطار العمل الدوت نت على Package Manager متكامل اسمه NuGet بحيث تستطيع من خلاله ما يلي:
- البحث وتنزيل المكتبات اللازمة إلى مشروعك (يقوم ايضاً بتنزيل متطلبات هذه المكتبة إن وجدت)
- مشاهدة ومتابعة جميع المكتبات المثبتة إلى مشروعك.
- آلية لتحديث المكتبات التي صدر منها اصدرات جديدة
- آلية لحذف مكتبة معينة من مشروعنا (مع باقي متطلباتها)
آلية عمل NuGet تقوم على إنشاء ملف (packages.config) ضمن ملفات مشروعك، ومن خلاله يمكنه إدارة المكتبات بشكل كامل. لنلقي نظرة على شكل هذا الملف من ضمن مشروع ASP.NET
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Antlr" version="3.4.1.9004" targetFramework="net45" />
<package id="bootstrap" version="3.1.1" targetFramework="net45" />
<package id="Bootstrap.Datepicker" version="1.3.0" targetFramework="net45" />
<package id="bootstrap-rtl" version="3.3.6" targetFramework="net46" />
<package id="EntityFramework" version="6.1.3" targetFramework="net45" />
<package id="HelperMethods.HTMLHelper" version="1.0.0" targetFramework="net45" />
<package id="jQuery" version="3.3.1" targetFramework="net45" />
<package id="jQuery.Validation" version="1.11.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Cors" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net46" />
<package id="Microsoft.AspNet.Identity.EntityFramework" version="2.2.1" targetFramework="net46" />
<package id="Microsoft.AspNet.Identity.Owin" version="2.2.1" targetFramework="net46" />
<package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="3.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net46" />
<package id="Microsoft.AspNet.WebApi" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.Cors" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="3.2.3" targetFramework="net45" />
<package id="Microsoft.Azure.KeyVault.Core" version="1.0.0" targetFramework="net45" />
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="1.0.0" targetFramework="net45" />
<package id="Microsoft.DependencyValidation.Analyzers" version="0.9.0" targetFramework="net45" />
<package id="Microsoft.jQuery.Unobtrusive.Ajax" version="3.2.4" targetFramework="net45" />
<package id="Microsoft.jQuery.Unobtrusive.Validation" version="3.2.3" targetFramework="net45" />
<package id="Microsoft.Net.Compilers" version="1.0.0" targetFramework="net45" developmentDependency="true" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Host.SystemWeb" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Security" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Security.Cookies" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Security.Facebook" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Security.Google" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Security.MicrosoftAccount" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Security.OAuth" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Security.Twitter" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net46" />
<package id="Modernizr" version="2.6.2" targetFramework="net45" />
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net46" />
<package id="Respond" version="1.2.0" targetFramework="net45" />
<package id="RestSharp" version="105.2.2" targetFramework="net45" />
<package id="Rotativa.Core" version="2.0.0" targetFramework="net45" />
<package id="Rotativa.MVC" version="2.0.3" targetFramework="net45" />
<package id="Twilio" version="4.7.2" targetFramework="net45" />
<package id="WebGrease" version="1.5.2" targetFramework="net45" />
<package id="WindowsAzure.Storage" version="9.3.3" targetFramework="net45" />
</packages>
نلاحظ ان الملف يحوي على مكتبات مختلفة من مطورين مختلفين.
وفيما يلي يظهر NuGet Package Manager من داخل Visual Studio ويظهر فيه ثلاث اقسام رئيسية:
- Browse وتمكنك من البحث عن المكتبات من مصادر مختلفة
- Installed وتمكنك من مشاهدة المكتبات المثبتة على مشروعك
- Updates وتمكنك من ترقية المكتبات إلى الاصدارات الجديدة
Node JS كمثال
يمكنك ايضا استخدام npm او (Node Package Manager)، وهي ايضا عبارة عن سوفت وير، تقوم بتثبيه على جهازك، ويمكنك بعدها ادارة المكتبات لاي مشروع، مهما كانت التنقية المستخدمة.
يعمل npm بنفس الية NuGet بحيث يقوم بتعريف بتنظيم جميع المكتبات داخل ملف واحد، ويقوم ايضا بمتابعة الاصدارات المختلفة منها. وبالطبع كما نشاهد في الصورة، فإن npm يعتمد على أوامر المستخدم او Command line، لادارة المكتبات عكس NuGet التي تقدم واجهات رسومية للمستخدم، لكن كما قلنا، الهدف والنتيجة واحد.
للمزيد حول Node JS يرجى زيارة الرابط التالي https://nodejs.org
يمكنك تنزيل NodeJS من هنا