
مرحبا حبر! أنا Miloš من Badoo ، وهذا هو أول منشور لي Habr ، نُشر في الأصل في
مدونة التقنية الخاصة بنا. آمل أن تكونوا مثل ذلك ، يرجى المشاركة والتعليق إذا كان لديك أي أسئلة
إذاً ... رد فعل ، أميريت ؟؟؟
لقد ظهر في منتصف العقد (الذي ابتليت به حروب إطار جافا سكريبت التي لا نهاية لها) ، واحتضنت
DOM ، صدمت الجميع من خلال مزج HTML مع جافا سكريبت وتحويل مشهد تطوير الويب إلى درجة لا يمكن التعرف عليها.
كل هذه الإنجازات ، دون
أن يكون إطارًا .
أحبها أو كرهها ، React تقوم بعمل جيد حقًا ، وهو HTML templating. جنبا إلى جنب مع مجتمع كبير ونظام بيئي صحي ، ليس من الصعب أن نرى لماذا أصبحت واحدة من مكتبات جافا سكريبت الأكثر شعبية وتأثيرا ، إن لم يكن الأكثر شعبية على الإطلاق.
هنا في فريق Mobile Web ، لا نتبع أي أطر JS صارمة - أو على الأقل ، أي منها شائع - ونحن نستخدم مزيجًا من التقنيات القديمة والتقنيات الحديثة. على الرغم من أن ذلك يعمل بشكل جيد بالنسبة إلينا ، إلا أن التعامل مع DOM عادة ما يكون أمرًا صعبًا ، وأردنا تخفيف ذلك عن طريق تقليل عدد التحديثات "اليدوية" ، وزيادة إعادة استخدام الكود لدينا والقلق بشأن تسريبات الذاكرة.
بعد إجراء بعض التحقيقات ، اعتبر React الخيار الأفضل وقررنا الذهاب معه.
انضممت إلى Badoo في منتصف هذه العملية. بعد أن قمت بتمهيد مشروع "React" وعملت عليه سابقًا ، كنت على دراية بميزاته وسلبياته في الممارسة العملية ، لكن ترحيل تطبيق ناضج مع
مئات الملايين من المستخدمين يمثل تحديًا مختلفًا تمامًا.
Jsx
React يمزج HTML مع جافا سكريبت بتنسيق اسمه
JSX . على الرغم من أنها تبدو وكأنها لغة نموذجية ، إلا أن JSX هو في الواقع مجرد بناء جملة أو
سكر نحوي ، إذا أردت ، في مكالمات React ، تشبه إلى حد كبير HTML.
تم تنظيم ملفات HTML الخاصة بنا بشكل جيد ، وتم إجراء معظم عمليات العرض الخاصة بنا ببساطة مثل
template.render()
. كيف يمكننا الاحتفاظ بهذا الترتيب والبساطة أثناء الانتقال إلى React؟ بالنسبة لي ، بصرف النظر عن الصعوبات التقنية ، كانت فكرة واحدة واضحة: استبدل مكالماتنا الحالية برمز JSX.
بعد بعض التخطيط الأولي ، أعطيته أداة "سطر الأوامر" التي اختتمت تنفيذ أمرين بسيطين:
- يقرأ القوالب المشار إليها في ملف واجهة المستخدم (JavaScript)
- استبدل مكالمات
template.render()
بمحتوى HTML
بالطبع ، لن يؤدي هذا إلى تحريكنا إلا في منتصف الطريق ، لأنه لا يزال يتعين علينا تعديل شفرة HTML يدويًا. النظر في حجم وعدد القوالب لدينا ، كنت أعرف أن أفضل نهج سيكون شيء الآلي. بدت الفكرة الأصلية بسيطة بما يكفي - وإذا أمكن شرحها ، فيمكن تنفيذها.
بعد تقديم الأداة الأولية لزملائه ، كان أفضل تعليق تلقيته هو وجود
محلل متاح للغة التجريبية التي استخدمناها. هذا يعني أنه يمكننا تحليل الشفرة وترجمتها بشكل أسهل بكثير مما يمكننا مع
التعبيرات العادية ، على سبيل المثال. وذلك عندما كنت أعرف حقا أن هذا سوف ينجح!
حسنًا ، بعد عدة أيام وُلدت أداة لتحويل
قوالب Dust.js المشابهة لـ HTML إلى رمز
JSX React . استخدمنا Dust ، لكن مع توفر عدد كبير من المحللون ، يجب أن تكون العملية مماثلة لترجمة أي لغة أخرى معروفة.
لمزيد من التفاصيل الفنية ، انتقل إلى قسم المصادر المفتوحة أدناه. استخدمنا أدوات مثل
Esprima لتحليل كود JS ،
ومولد محلل
PEG.js لتحليل قوالب الغبار. في أبسط المصطلحات ، يتعلق الأمر بترجمة هذا النوع من رمز القالب:
<div class="encounters {?isExpanded}is-expanded{/isExpanded}"> {?showTooltip} <div class="tooltip"> <span>{#_t}{encounters_tooltip}{/_t}</span> <div class="icon"> {@Icon name="icon-encounters" size="stretch" /} </div> </div> {/showTooltip} <div class="images"> {#images} <img src="{src}"> <input type="radio" id="{id}" {?selected}checked{/selected} /> <label for="showme-{id}"> {name} </label> {/images} </div> <div class="footer"> {! encounters-footer template will be injected here !} </div> </div>
إلى مكافئ كود JSX الخاص به:
<div className="encounters {props.isExpanded ? 'is-expanded' : ''}"> {props.showTooltip ? <div className="tooltip"> <span>{i18n.get('encounters_tooltip')}</span> <div className="icon"> <Icon name="icon-encounters" size="stretch" /> </div> </div> : null} <div className="images"> {props.images.map(item => <img src={item.src}> <input type="radio" id={`showme-${item.id}`} defaultChecked={item.selected ? true : undefined} /> <label htmlFor={`showme-${item.id}`}> {item.name} </label> )} </div> <div className="footer"> {/* encounters-footer template will be injected here */} </div> </div>
انظر مقارنة جنبا إلى جنب
هنا .
بعد ذلك ، كانت عمليتنا واضحة إلى حد كبير. قمنا تلقائيًا بتحويل القوالب الخاصة بنا من تنسيق إلى آخر ، وعمل كل شيء كما هو متوقع (شكرًا لك ، الاختبار التلقائي). بادئ ذي بدء ، حافظنا على API
template.render()
القديمة الخاصة بنا للحفاظ على التغييرات معزولة.
بالطبع ، مع هذا النهج ، لا يزال بإمكانك الوصول إلى قوالب وليس مكونات React "الصحيحة". تتمثل الفائدة الحقيقية في أنه من الأسهل كثيرًا ، إن لم يكن تافهًا ، التبديل إلى React من القوالب التي هي بالفعل JSX ، في معظم الحالات ببساطة عن طريق لف رمز القالب في استدعاء دالة.
قد تظن: لماذا لا تكتب قوالب جديدة من الصفر بدلاً من ذلك؟ الإجابة المختصرة هي أنه لم يكن هناك شيء خاطئ في القوالب القديمة - لقد كان لدينا الكثير منها. أما بالنسبة لإعادة كتابتها والعمل نحو
تكوين حقيقي ،
فهذه قصة مختلفة .

قد يجادل البعض بأن
نموذج المكون هو مجرد اتجاه آخر قد يمر ، فلماذا الالتزام به؟ من الصعب التنبؤ ، ولكن أحد الإجابات المحتملة هو أنه
ليس عليك القيام بذلك . إذا قمت بالتكرار بسرعة ، فيمكنك تجربة خيارات مختلفة ، دون إنفاق الكثير من الوقت على أي منها ، حتى تجد التنسيق الذي يناسب فريقك. هذا أحد المفاهيم الأساسية لنا على Badoo.
مع ظهور ES7 / 8 / Next ، Elm و Reason ، ناهيك عن TypeScript والحلول المشابهة ، أصبح الكود الذي كان مرة واحدة
*.js
يتعذر تمييزه أكثر فأكثر من JavaScript ، ويبدو أن هذا الاتجاه سيستمر. بدلاً من أن تطغى عليها ، لماذا لا تستخدم هذا لصالحنا؟
المصدر المفتوح
انطلاقًا من
عمل شيء واحد جيدًا ، قمنا ببناء هذه الأدوات الداخلية في عدة أجزاء:
- dust2jsx - الحزمة المسؤولة عن الترجمة الفعلية للغبار إلى jsx
- ratt (React All The Things) - أداة سطر الأوامر لقراءة / كتابة الملفات على القرص. مسؤول عن تضمين القوالب المرجعية ، ويستخدم
dust2jsx
داخليًا لتحويل الشفرة
لقد فتحنا هذه الأدوات من المصادر المفتوحة - تأكد من التحقق منها ، وكذلك المواد الأخرى مفتوحة المصدر على صفحة
جيثب الخاصة بنا. الرجاء المساهمة أو ببساطة ترك تعليق لنا إذا وجدت أنها مفيدة.