القصة وراء مكتبة رياكت

حُدثت في

أثناء محاولتي لتطوير مقالة رياكت في ويكيبيديا العربية، اتضطررت للرجوع قليلًا إلى تاريخ رياكت، كيف بدأت ولماذا اخترعتها فيسبوك ومن الشخص الذي اخترعها… كانت قصة مثيرة… عن تلك المشاكل التي كانت تواجه مطوري الويب آنذاك والحل الذي أتت به رياكت.

نبذة سريعة عن رياكت

رياكت هي مكتبة جافاسكربت، متخصصة بواجهات المستخدم التفاعلية (Interactive UI) تُستخدم بشكل شائع في الكثير من المواقع وحتى في تطوير تطبيقات الهواتف. تم إتاحة المكتبة كمشروع مفتوح المصدر في عام 2013، وكما تم العمل على تطوير تقنية رياكت نتيف في 2015 وإتاحتها كمشروع مفتوح المصدر كذلك. مضت 9 سنوات -لحظة كتابة هذه التدوينة- على الإطلاق الرسمي لرياكت أي قرابة عقد من الزمان، خلالها تطورت المكتبة نفسها وطورت معها حتى طرق التفكير والبرمجة في واجهات المستخدم.

القصة

لتدرك الهدف والفائدة من رياكت عليك أن تدرك كيف وصلنا إلى هذه النقطة وكيف أصبحت رياكت بهذا الحجم والشهرة.

البدايات

تبدأ القصة عام 2011 في داخل شركة فيسبوك -شركة ميتا حاليًا- أحد المُطورين ويُدعى جوردان والكي (Jordan Walke) هو وزملائه بالعمل كانوا مدركين لمشكلة “تعقيد بناء التطبيقات الويب”، خصوصًا فيما يتعلق بواجهات المستخدم (UI) عندما تصبح واجهة المستخدم أكبر وأعقد مع مرور الوقت واستمرار التطوير عليها، فيُصبح من الصعب إدارتها والتعديل عليها وصيانتها.

مكتبات التعامل مع واجهة المستخدم في ذلك الوقت لم تكن تقدم الحل المناسب بحسب وجهة نظر جوردان فهي بحاجة لكثير من التفاصيل، وكلما كبر المشروع أكثر فأكثر تجعل المبرمج يفكر في أمور أخرى أكثر من تفكيره في واجهة المستخدم ذاتها، أحد أهم هذه الأمور هو التفكير في التغييرات التي يلزُم أن تتم على العناصر في الصفحة (Dom Mutation) عندما يتفاعل المستخدم أحد المكونات في الواجهة.

أراد جوردان شيئًا مختلفًا، شيئًا أقل تعقيدًا من وجهة نظره، لذلك قرر العمل فكرة وعرضها على زملاءه في العمل بفيسبوك وذلك بإنشاء مكتبة FaxJS كنموذج مبدئي (قبل أن يتم تسمية المشروع React)، وفكرتها هي أن تساعد على إنشاء العناصر التفاعلية بطريقة برمجية تصريحية (Declarative) وعبر جوردان عن فكرته بأنها “طريقة لإنشاء مُكونات تصريحية (Declarative Components)” أي مفهومة وواضحة، على خلاف الطريقة الأمرية (imperative) التي تتطلب ذكر تفاصيل كثيرة، وبدلًا من أن ينشغل بالك بكل التفاصيل، ليس عليك إلا قول ما تريد فعله “تصريحه”. وحتى لا تتعقد الأمور ويتشتت التفكير في البيانات وتغيراتها، أراد جوردان وأصدقائه أيضًا أن يتم تتبع كل تلك التغيرات (Dom Mutation) وتصيرها في العناصر بطريقة سهلة دون التفكير في تفاصيلها، وفي وقتٍ لاحق قام الفريق أيضًا بتوفير طريقة كتابة اختيارية لعناصر الواجهة سُميت (JSX) تُساعد على وصف شكل المكون بسهولة وقد أستلهمت من Ecmascript For Xml و XHP.

قدم توم أوكينو (Tom Occhino) هو وجوردان والكي (Jordan Walke) مكتبة رياكت للعيان في حدث JSConf US 2013 التي عمل عليها هو وفريق من موظفي فيسبوك وقد تم جعلها مشروعًا مفتوح المصدر قبل العرض بـ نصف ساعة.

صورة لطريقة كتابة JSX من العرض التقديمي الأول لرياكت في عام 2013 والذي قدمه جوردان في JSConf US.
صورة لطريقة كتابة JSX من العرض التقديمي الأول لرياكت في عام 2013 والذي قدمه جوردان في JSConf US.
صورة للكود ذاته ولن بدون JSX. مأخؤذة من عرض جوردان التقديمي JSConf US 2013.
صورة للكود ذاته ولن بدون JSX. مأخؤذة من عرض جوردان التقديمي JSConf US 2013.

أشار جوردان في العرض أن الهدف من رياكت لا يقتصر فقط بتقديم طريقة سهلة لوصف العناصر (عناصر HTML) برمجيًا، بل أيضًا توفير إمكانية لإعادة استخدامها كمكون مخصص (Custom Component)، بطريقة مُبسطة ومُجردة بكل سهولة.

مكون رياكت (React Component) قابل لإعادة الإستخدام في الأعلى طريقة تعريف المكون، بينما في الأسفل طريقة إعادة استخدام المكون، من عرض جوردان JSConf US 2013.
مكون رياكت (React Component) قابل لإعادة الإستخدام في الأعلى طريقة تعريف المكون، بينما في الأسفل طريقة إعادة استخدام المكون، من عرض جوردان JSConf US 2013.

طريقة القولبة (templating) في JSX مرنة جدًا، ليست مقتصرة على تمرير النصوص بين المكونات، بل حتى تمرير بعض العمليات البرمجية على هيئة دوال (Functions).

جوردان يوضح للحضور إمكانية تمرير دالة للمكون واستخدماها مع الأحداث حيث استخدمها مع الحدث "onClick", الصورة مأخوذة من JSConf US 2013.

جوردان يوضح للحضور إمكانية تمرير دالة للمكون واستخدماها مع الأحداث حيث استخدمها مع الحدث "onClick", الصورة مأخوذة من JSConf US 2013.

يتيح JSX ايضًا تنفيذ تعبيرات جافاسكربت في داخل القالب نفسه، ويتم تطبيق تلك التغيرات دومًا عند تغير حالة المكون.

يوضح جوردان، إمكانية وضع تعبير جافاسكربتي داخل القالب وقد قام بتطبيق وظيفة toUpperCase التي تجعل اﻷحرف الإنجليزية كبيرة، صورة من عرض جوردان JSConf US 2013.

يوضح جوردان، إمكانية وضع تعبير جافاسكربتي داخل القالب وقد قام بتطبيق وظيفة toUpperCase التي تجعل اﻷحرف الإنجليزية كبيرة، صورة من عرض جوردان JSConf US 2013.

وبهذه الطريقة سوف تحصل على “مكون” يؤدي وظيفة معينة، هذا المكون تستطيع إعادة أستخدامه مرارًا وتكرارًا في أجزاء مختلفة من واجهة المستخدم.

رياكت لا تجعلك تفكر في البيانات في الجهتين (two-way data binding) من منظور MVC بل تفكر في البيانات من منطلق أُحادي الإتجاه (one-directional data binding) حيث لا تلقي رياكت أي أهتمام بالتغييرات (Mutation) التي سوف تطرأ على الحالة في المكون وعندما تتغير حالة البيانات تقوم رياكت بإعادة توليد المكون من جديد بالكامل.

تبدو فكرة سخيفة نوعًا ما وليست ذات كفاءة وهذا ما قاله توم أوكينو (Tom Occhino) للحضور أثناء بداية العرض واستعراض رياكت، وشرح لهم أن رياكت أتت بحل وهو عمل نسخة من المستند الحالي (DOM) وإجراء التغييرات فيها ومن ثم مقارنة تلك التغييرات مع المستند الفعلي وتطبيق ما تم تغييره وهذا ما يسمى بـ VDOM (Virtual DOM). وأشار توم أيضًا إلى أنه قد تم استخدام رياكت بالفعل في مشاريع داخلية في فيسبوك على موقع فيسبوك الرسمي، وعلى منصة انستجرام قبل الإطلاق الرسمي للمكتبة بحاولي 18 شهرًا… و وجدوا أنها قدمت لهم حلًا رائعًا يمكن الإعتماد عليه لذلك قرروا جعلها مشروع مفتوح المصدر ومشاركة ما توصلوا إليه مع جميع المطورين الآخرين.

ردة الفعل

عندما تأتي بفكرة جديدة خارجة عن المعتاد، سترى أن العديد لن يتفق معك، وهذا ما حدث تمامًا مع رياكت العديد من التعليقات الناس الذين عبروا أنهم لم يحبوا الطريقة التي جاءت بها رياكت بدمج المنطق البرمجي (Logic) مع القالب المرئي (Display template) معًا حيث عبّر الكثير عن عدم إعجابهم بفكرة JSX وأشار بيّت هات (Pete Hunt) -أحد العاملين في فريق رياكت- في عرضٍ تقديمي له على JSConf EU 2013 -لقاء حدث بعد عدة أشهر من اللقاء الاولى الذي أطلقت فيه رياكت- إلى سوء فهم حصل من الناس حيث أنهم تعودوا على فصل إهتمامتهم على أساس أنها قوالب وليست مُكونات، لذلك لم يعجبوا بهذا النمط من التصميم.

وأيضًا وضح بيّت أنه حين التعامل مع واجهة المستخدم على أساس أنها مكونات فإنه يسهل إمكانية إجراء بعض الإختبارات المؤتمة عليها تحديدًا (Units Test) بكل سهولة وسلاسة، كما يسهل إمكانية إعادة استخدام المكونات وتعديلها حيث تصب تركيزك على قطعة واحدة من الكود وتكون منفصلة عن باقي الكود.

أحد الإشكاليات التي تصورها الناس بسبب طريقة رياكت في دمج المنطق البرمجي مع الواجهة المرئية هي سهولة خلط الكود وإنشاء ما يسمى بـ(Spaghetti code) الكود الملغوص -المتداخل- حيث سيصبح من الصعب إدارة الكود بسبب كل تلك الاشياء المتشابكة والمتداخلة، وكانت إجابة بيّت هي أن لا تكتب كود متداخل (Spaghetti code) بكل بساطة، وحاول إبقاء المكونات صغيرة قدر الإمكان وذلك بالتركيز على وضع المنطق البرمجي الذي تحتاجه المكونات في الواجهة المرئية فقط، وليس وضع اشياء قد لا تكون لها علاقة بالواجهة بشكل مباشر مثل جلب البيانات من الشبكة (Fetching Data) وعمليات التحقق (Validation) حيث يجب أن لا يوضع هذا النوع من المنطق البرمجي في داخل المكونات التي تبني واجهة المستخدم.

أثارت رياكت أيضًا مخاوف لدى بعض الأشخاص، لأنها تقوم بتوليد المكونات على المتصفح وهذا قد يسبب نوع من الثغرات تُسمى XSS، وكانت إجابة بيّت أن فريق رياكت قام بإنشاء مكتبة ReactDOM وهي مكتبة تقوم بتوليد عناصر HTML بطريقة سهلة ومع الأخذ بعين الإعتبار تجنب المخاطر الأمنية، وأيَضًا أشار إلى أنه عند كتابة JSX فإنه يتم ترجمتها إلى دوال عادية في ReactDOM وهي التي تقوم بتشكيل العناصر.

رأى بعض الناس أن توليد العناصر في المتصفح فكرة سيئة للـ SEO حيث أن زواحف الويب (Web Crawlers) قد لا تعرف محتوى الصفحة، رد بيّت على هذا الكلام بأنه يمكن الآن إنشاء نسخة من مستند الـ DOM الإفتراضي على الخوادم (Web Servers) وذلك عن طريق NodeJS ومن ثم إرسالها إلى المستخدم وستقوم رياكت فقط بضبط مُستمعات الأحداث (Event listener) عند تحميل الصفحة ومن ثم تمكين المستخدم من التفاعل مع الصفحة بشكل عادي دون انتظار توليد العناصر على الصفحة.

المستقبل، رياكت نيتف

أحد المشاكل الداخلية في فيسبوك كانت تطوير تطبيقات منصة فيسبوك للهواتف، في ذلك الوقت كان فيسبوك مجرد موقع ويب، ومع ظهور الهواتف المحمولة كان على فريق فيسبوك بناء تطبيقات للهواتف الذكية حتى لا يتم فقد الناس الذين يستخدمون هواتفهم الذكية.

المشكلة

حاول المطورون في فيسبوك إنشاء تطبيقات هواتف بالمفهوم الهجين (Hybrid App) بمعنى تشغيل صفحة ويب في داخل WebView، ولكن هذا النمط من البرمجة لم ينجح معهم، وفي حدث React.js Conf 2015 صرح توم أوكينو قائلًا: “يرجع السبب لأن بناء تطبيقات الويب (Web App)، وجعلها تحاكي عمل تطبيقات الهواتف الأصلية (Native)، يُقدم تجربة مستخدم سلبية.” تملك تطبيقات الهواتف طابعًا فريدًا يصعب على تطبيقات الويب تقليده، وقد يكون تقليده على الويب أشبه بالمستحيل ويرجع لذلك لإمكانية استغلال كامل قدرات الجهاز في التطبيقات الأصلية (Native) ما يقدم تجربة مستخدم سلسلة ومرنة مقارنة بالويب الذي لديه وصول محدود لموارد الجهاز.

ومع كل هذه الامكانيات التي تقدمها تطبيقات اﻷصلية إلا أنها تضيف العديد من التعقيدات في مراحل التطوير، فتطوير تطبيقات الهواتف باستخدام التقنيات الأصلية، أمر متعب ومُجهد. ليس ذلك فقط بل أن نفس المشكلة التعقيد التي جاءت رياكت لحلها موجودة بشكل مشابه في تطبيقات الهواتف الذكية الاصلية (Native).

بإمكان رياكت احتواء أي نظام عرض (View System) ليس فقط مستند DOM، وهنا ظهرت الفكرة… ماذا لو تم أخذ نفس المفهوم الذي تستخدمه رياكت تمامًا في الويب ولكن بدلًا من التعامل مع عناصر DOM يتم التعامل مع المكونات الأصلية (Native Components) على مستوى نظام التشغيل؟

الحل

وهذا ما تم فعله، قام فريق رياكت بأبتكار تقنية جديدة سميت رياكت نيتف (React Native) وهي تستخدم نفس مفهوم رياكت على الويب، ولكن يكمن الفرق الجوهري في تعاملها مع المكونات الأصلية في نظام التشغيل بدلًا من عناصر HTML على المتصفح. قام توم اوكينو باستعراض تطبيق مكتوب باستخدام رياكت نيتف مباشرًا أمام الجمهور في حدث React.js Conf 2015 ووضح للجمهور قوة رياكت نيتف وأدائها، كما علق توم مازحًا “أشعر أني الآن أبدو وكأنني ستيف جوبز”.

تطورات رياكت، والشهرة

مع مرور الوقت شيئًا فـشيئًا أصبحت رياكت تقنية شهيرة في عالم جافاسكربت والعديد من الأشخاص والشركات تستخدمها، لاحظ الفريق الذي يعمل على تطوير وصيانة مكتبة رياكت هذا الأمر، وفي 2016 ثم إطلاق مشروع Create React App الشهير وهو عبارة عن سكربت بسيط يقوم بتجهيز بيئة عمل أساسية لمشاريع رياكت جديد من خلال مدير حزم جافاسكربت (NPM)، فكل ما عليك هو فتح سطر الأوامر وكتابة اﻷمر npx create-react-app وسيتم تجهيز مشروع رياكت مع كافة الإعدادات الإفتراضية المستحسنة مضبوطة مسبقًا لـكل من مُجمع الوحدات (المحزم) WebPack و المترجم babel-js لتسهيل عملية تطوير تطبيقات الويب باستخدام مكتبة رياكت دون الغوص والضياع في تفاصيل إعداد وتجهيز بيئة عمل المشروع.

خلاصة الموضوع

جاءت مكتبة رياكت كحل لمشاكل كانت تواجه مطوري الويب في فيسبوك، تلك المشاكل جاءت بحلول ليست إعتيادية وهذا يوضح أهمية التجربة العملية في مجال البرمجة والحاسب بشكل عام، تبدو فكرة رياكت نظريًا مكلفة من ناحية الأداء، ولكن مع بعض الحلول التي طبقها الفريق الذي عمل وراءها حصلوا على طريقة سهلة مكنتهم من تسريع وتيرة عملهم وتبسيطها والحفاظ على الأداء.