CSS-in-JS ، كونها ليست تقنية جديدة تمامًا وتنفيذها في العديد من المكتبات ، لا تزال تثير الشكوك والنقاشات حول مدى ملاءمة استخدامها. Gajus Kuizinas ، مؤلف وحدات تفاعلية css- plugins و babel plugin ، وضع نقاطه على "i" في النزاعات حول CSS-in-JS بشكل عام ، وحول المكونات ذات النمط على وجه الخصوص ، قبل عام ، (27 أبريل 2017) -react-css-modules ، في رأيي الحالي المنشور "توقف عن استخدام CSS-in-JavaScript في تطوير الويب" .
فيما يلي ترجمة مختصرة قليلاً مع بعض الإضافات والاستنتاجات:
لا تذهب CSS إلى أي مكان . في العديد من المشاريع ، يكون اختيار التصميم في JavaScript خاطئًا. سنذكر المفاهيم الخاطئة الشائعة (الأساطير) وقراراتها المقابلة من خلال CSS.
تاريخ Css و JavaScript
تم إنشاء CSS لوصف عرض مستند مكتوب بلغة ترميزية. تم إنشاء JavaScript كـ "غراء لغوي" لتجميع المكونات مثل الصور والمكونات الإضافية. على مر السنين ، نمت JS وتغيرت ، لتتكيف مع مجالات التطبيق الجديدة. ونتيجة لذلك ، نحن نعيش اليوم في عصر التطبيقات ذات الصفحة الواحدة (SPA) ، التطبيقات المجمعة من المكونات.
ماذا عن CSS؟
فيما يلي اقتباس من وثائق المكونات ذات النمط :
مشكلة CSS العادية هي أنه تم إنشاؤه في عصر كان الويب يتكون من مستندات. تم إنشاء الويب لتبادل الوثائق العلمية في عام 1993 وتم تقديم CSS كحل لتصميم هذه المستندات. ومع ذلك ، نقوم اليوم بتطوير تطبيقات متطورة وتفاعلية وموجهة للمستخدم ، وببساطة لم يتم تصميم CSS لهذا الغرض.
الأمر ليس كذلك.
تأخذ CSS بالفعل في الاعتبار جميع متطلبات واجهات المستخدم الحديثة. عدد الوظائف الجديدة التي تم تنفيذها في العقد الماضي لدرجة أنه من المستحيل إدراجها جميعًا (الفئات الزائفة ، العناصر الزائفة ، متغيرات CSS ، استعلامات الوسائط ، الإطارات الرئيسية ، المولدات ، الأعمدة ، المرن ، الشبكة ، القيم المحسوبة ، ...).
من وجهة نظر واجهة المستخدم ، "المكوِّن" هو جزء معزول من المستند (<button /> هو "مكوِّن"). تم تصميم CSS لنمط المستندات ، ويغطي المستند جميع المكونات. ما هي المشكلة؟
كما يقول المثل: "استخدم الأداة المناسبة للمهمة".
مكونات على غرار
المكونات ذات النمط تجعل من الممكن كتابة CSS في JavaScript باستخدام ما يسمى سلاسل قالب الموسومة . تزيل المكتبة التعيين بين المكونات والأنماط - يتحول المكون إلى بنية نمط منخفضة المستوى ، على سبيل المثال:
// Create a <Title> react component that renders an <h1> which is // centered, palevioletred and sized at 1.5em const Title = styled.h1` font-size: 1.5em; text-align: center; color: palevioletred; `;
أصبحت عناصر التصميم شائعة اليوم وتعرف بأنها طريقة جديدة لمكونات التصميم في React ، على الرغم من أنها تُعرض أحيانًا على أنها "قمة تطوير CSS":
تطور CSS: من وحدات CSS و SASS و BEM و CSS إلى المكونات ذات النمط .
لكن دعنا نوضح ما يلي: المكونات ذات النمط هي مجرد إضافة CSS. تقوم هذه المكتبة بتحليل أنماط CSS التي تحددها في JavaScript وإنشاء عناصر JSX المناسبة.
إن شعبية المكونات ذات النمط المشحون محفوفة بالعديد من المفاهيم الخاطئة. جعلت مراجعة إجابات المبرمجين (الموجودة في IRC و Reddit و Discord) على سؤال حول الأسباب التي دفعتهم إلى استخدام هذه المكتبة من الممكن عمل قائمة بأكثرها ذكرًا. دعونا نطلق عليهم الأساطير.
الخرافة الأولى: المكونات ذات النمط تحل مشاكل مساحة الاسم العالمية وتضارب الأنماط
هذه أسطورة ، لأنه يبدو أن المشكلة المزعومة المذكورة لم يتم حلها بعد. ومع ذلك ، قدمت CSS Modules و Shadow DOM واتفاقيات تسمية لا حصر لها (مثل BEM ) حلولًا للمشكلة منذ فترة طويلة.
المكونات ذات النمط (تمامًا مثل وحدات CSS) تزيل مسألة مسؤولية التسمية من الشخص. من الخطأ البشري أن يرتكب الأخطاء ؛ فالكمبيوتر لا يرتكب أخطاء في أغلب الأحيان.
في حد ذاته ، هذا ليس سببًا جيدًا بما يكفي لاستخدام المكونات ذات النمط.
الخرافة 2: استخدام المكونات ذات النمط يجعل من الممكن الحصول على كود مضغوط أكثر.
لدعم هذا ، غالبًا ما يتم إعطاء مثال:
<TicketName></TicketName> <div className={styles.ticketName}></div>
بادئ ذي بدء ، لا يهم. الفرق لا يكاد يذكر.
ثانيا ، هذا ليس صحيحا. يعتمد العدد الإجمالي للأحرف على اسم النمط.
<TinyBitLongerStyleName></TinyBitLongerStyleName> <div className={styles.longerStyleName}></div>
وينطبق الشيء نفسه على إنشاء الأنماط ، والتي سنراها لاحقًا في هذه المقالة.
(الأسطورة الخامسة: المكونات ذات النمط تسهل التصميم الشرطي للمكونات). تفوز المكونات ذات الأنماط باختصار فقط في حالات المكونات الأساسية.
الخرافة 3. إن استخدام المكونات ذات النمط يجعلك تفكر أكثر في علم الدلالات.
الرسالة الأصلية نفسها خاطئة. إن الأسلوب وعلم الدلالة مشاكل مختلفة وتتطلب حلولاً مختلفة. اقرأ ، على سبيل المثال ، هذا آدم مورس .
ومع ذلك ، فكر في:
<PersonList> <PersonListItem> <PersonFirstName>Foo</PersonFirstName> <PersonLastName>Bar</PersonLastName> </PersonListItem> </PersonList>
يتعامل علم الدلالات مع استخدام العلامات الصحيحة للترميز. هل تعرف ما هي علامات HTML التي سيتم استخدامها لتقديم مثل هذا المكون؟ لا ، أنت لا تعرف.
قارن:
<ol> <li> <span className={styles.firstName}>Foo</span> <span className={styles.lastName}>Bar</span> </li> </ol>
الخرافة الرابعة: من الأسهل توسيع الأنماط.
قارن:
const Button = styled.button` padding: 10px; `; const TomatoButton = Button.extend` color: #f00; `;
عظيم! ولكن يمكنك فعل الشيء نفسه في CSS (أو استخدام تكوين وحدة CSS ، بالإضافة إلى مزيج وراثة SASSextend).
button { padding: 10px; } button.tomato-button { color: #f00; }
وأبسط الخيار الأول؟
خرافة 5: التسهيل الشرطي للمكونات
الفكرة هي أنه يمكنك تصميم العناصر باستخدام الدعائم ، على سبيل المثال:
<Button primary /> <Button secondary /> <Button primary active={true} />
هذا منطقي في رد الفعل. في النهاية ، يتم التحكم في سلوك المكونات من خلال الدعائم. هل من المنطقي ربط قيم الدعامة مباشرة بالأنماط؟ ربما. ولكن دعونا نلقي نظرة على تنفيذ مثل هذا المكون:
styled.Button` background: ${props => props.primary ? '#f00' : props.secondary ? '#0f0' : '#00f'}; color: ${props => props.primary ? '#fff' : props.secondary ? '#fff' : '#000'}; opacity: ${props => props.active ? 1 : 0}; `;
يوفر إنشاء أنماط شرطية باستخدام JavaScript الكثير من الاحتمالات. ومع ذلك ، هذا يعني أيضًا أنه سيكون من الصعب تفسير الأنماط. قارن مع CSS:
button { background: #00f; opacity: 0; color: #000; } button.primary, button.seconary { color: #fff; } button.primary { background: #f00; } button.secondary { background: #0f0; } button.active { opacity: 1; }
في هذه الحالة ، يكون CSS أقصر (229 حرفًا مقابل 222) ويسهل فهمه (ذاتيًا). علاوة على ذلك ، في CSS يمكنك استخدام معالج مسبق للحصول على نتيجة أقصر ومجمعة:
button { background: #00f; opacity: 0; color: #000; &.primary, &.seconary { color: #fff; } &.primary { background: #f00; } &.secondary { background: #0f0; } &.active { opacity: 1; } }
الخرافة 6: منظمة كود تتحسن
يقول البعض أنهم يحبون المكونات ذات الأنماط ، لأنه يصبح من الممكن وضع الأنماط والنصوص في ملف واحد. يمكنك أن تفهم أن وجود عدة ملفات لمكون واحد قد يبدو مملاً ، ولكن نقل الأنماط والتخطيط في ملف واحد أمر مروع. لن يعمل نظام التحكم في الإصدار هذا على تعقيد تغييرات التتبع فحسب ، بل سيؤدي أيضًا إلى "التمرير" اللانهائي على أي عنصر أكثر تعقيدًا من الزر البسيط.
إذا كنت بالتأكيد بحاجة إلى وضع CSS و JavaScript في نفس الملف ، فجرّب css-literal-loader . يتيح لك هذا الأخير إنشاء أنماط أثناء الإنشاء باستخدام extract-text-webpack-plugin واستخدام تكوين اللودر القياسي للتعامل مع CSS.
الخرافة السابعة: "تجربة المطورين (DX)" أصبحت رائعة. الأداة رهيبة!
من الواضح أنك لم تستخدم مكونات على غرار.
- إذا حدث خطأ في الأنماط ، يتعطل التطبيق بالكامل مع تتبع مكدس طويل للخطأ. عكس ذلك هو CSS ، حيث سيؤدي خطأ في الأنماط ببساطة إلى عرض غير صحيح للعنصر.
- لا تحتوي العناصر على className يمكن تمييزه ، لذلك أثناء التصحيح يجب عليك التبديل إلى ما لا نهاية بين شجرة عنصر التفاعل وشجرة DevTools DOM.
- على الرغم من وجود مكونات إضافية للتنزيل ، وتمييز الكود ، وإكمال الكود ، و "رموز" أخرى مماثلة بالفعل للمكونات ذات النمط ، فقد لا تزال غير متاحة لـ IDE. إذا كنت تعمل مع الشؤون المالية في وكالة حكومية ، فهناك احتمال أن يكون Atom IDE غير متاح.
الخرافة 8: كل شيء يصبح "أسرع" ، كل شيء يصبح "أسهل"
- كما اتضح ، لا يمكن استخراج أنماط المكونات ذات النمط إلى ثابت
ملف CSS (مثل استخدام extract-text-webpack-plugin ). وهذا يعني أن المتصفح لن يكون قادرًا على بدء تفسير الأنماط حتى تقوم المكونات ذات النمط بتحليلها وإضافتها إلى DOM. - يعني دمج الأنماط والبرامج النصية في ملف واحد أن التخزين المؤقت المنفصل غير ممكن.
- إن طبيعة المكونات المصممة بحيث يتم تغليفها جميعًا في HOC إضافي. وهذا انخفاض غير ضروري في الأداء. أدى نفس الخلل إلى وقف وحدات التفاعل المتفاعل وظهور الوحدات المتفاعلة - المتفاعلة - المتفاعلة .
- نظرًا لنفس HOC ، ينتج عن العرض من جانب الخادم أحجام ترميز مستندات أكبر بكثير.
- لا تحاول حتى تحريك المكونات باستخدام الأنماط الديناميكية بدلاً من الإطارات الرئيسية.
الخرافة 9: هناك إمكانية لتطوير مكونات "متجاوبة"
نحن نتحدث عن القدرة على تصميم عنصر بناءً على البيئة ، على سبيل المثال ، حجم الحاوية الأم ، وعدد الورثة ، وما إلى ذلك.
بادئ ذي بدء ، المكونات ذات النمط لا علاقة لها بهذا.
هذا خارج نطاق المشروع. في هذه الحالة ، من الأفضل تعيين قيم نمط المكونات مباشرةً لتجنب أحمال المعالج الإضافية.
انتظر دقيقة ، ولكن!
يمكن حل معظم هذه المشاكل ، إن لم يكن جميعها ، على المدى الطويل إما من قبل المجتمع ، أو من خلال التغييرات في رد الفعل أو في المكونات ذات النمط. لكن لماذا؟ CSS مدعوم بالفعل على نطاق واسع ، وهناك مجتمع قوي و ... إنه يعمل فقط.
ولكن يجب ألا تتجنب دائمًا استخدام CSS-in-JavaScript أو المكونات ذات الأنماط.
هناك شيء يجعل المكونات ذات النمط مكتبة جيدة - وهذا هو أفضل دعم عبر الأنظمة الأساسية.
فقط لا تستخدم مكونات على غرار تمثيلات خاطئة.
زوج من الآراء من الأطراف المعنية.
باستخدام المكونات ذات النمط في مشروعنا ، وجدنا أن هناك بعض قواعد النمط التي يصعب تنفيذها في المكونات ذات النمط ؛ على سبيل المثال ، القواعد التي تتحكم في وضع العناصر على الصفحة (الهوامش أو خاصية العرض). كان من الصعب التوحيد ، لذلك لا يزال علينا الاعتماد بشدة على CSS البسيط لوضع المكونات في دفق العناصر.
... على الرغم من وجود صعوبات في استخدام المكونات ذات النمط ، ساعدتنا المكتبة على تقليل قاعدة التعليمات البرمجية.
(تعليق على "تطور CSS: من CSS و SASS و BEM و CSS - الوحدات إلى المكونات ذات النمط" )
... لا يعني تطور CSS هنا أن الأدوات تتطور.
في رأيي ، لا توجد مشكلة عندما تنضج التنضيد في التخطيط ، ويشارك المبرمج في البرمجة.
ولكن عندما ينخرط المبرمجون في التنضيد ، تبدأ حديقة الحيوانات بأكملها ، والتي بدلاً من البساطة مع المزيد من الدعم ، تسبب صداعًا إضافيًا.
...
اكتب في CSS خالص ، وأعط الأدوات دور مساحة الاسم وجامع - عندها سيكون الجميع سعداء ...
وأخيرًا ، كلمة للمؤلف:
Gajus Kuizinas: - إذن ، ما الذي يجب استخدامه في النهاية؟