آرش منطقی،

طراح و توسعه‌دهنده رابط کاربری

همایش CoderConf و ارائه متدولوژی‌های توسعه فرانت‌اند

avatar

امروز افتخار این رو داشتم که تو همایش CoderConf به عنوان سخنران حضور داشته باشم و درباره متدولوژی‌های توسعه فرانت‌اند صحبت کنم. از اونجایی که این اواخر در این مورد یک پست مختصر نوشتم و به واسطه اندک تجربه‌ای که داشتم، این فرصت رو غنیمت شمردم تا این مباحث رو با قشر وسیع‌تری از توسعه دهنده‌ها در میون بزارم. خوشبختانه مقاله‌ام برای چاپ و ارائه توسط هیئت داوران قبول شد و به این ترتیب تونستم اطالاعاتی که داشتم رو به اشتراک بزارم.

اما با توجه به اینکه تعداد زیادی از دولوپرها هم در این کنفرانس حضور نداشتند و با توجه به اینکه خودم محتوای فارسی در این مورد ندیدم، لازم دونستم این مقاله به صورت کامل در وبلاگم منتشر کنم تا همه بتونن ازش استفاده کنن. پیشاپیش درخواست دارم در صورت انتشار این مطلب، منبع رو هم ذکر کنید. در ضمن، زبان این مقاله نوشتاری هست. در ادامه با متدولوژی‌های توسعه فرانت‌اند همراه باشید.

مقدمه
در دنیای امروز یکی از مباحث مورد توجه توسعه‌دهندگان تولید نرم‌افزارهایی با قابلیت توسعه مداوم و نگهداشت بالا است. در سال‌های اخیر در حوزه فرانت‌اند نیز به این مسائل توجه زیادی شده و متدولوژی‌های متفاوتی مطرح شده. این متدولوژی‌ها دارای اشتراکاتی با یکدیگر هستند در حالی که تناقض‌هایی نیز با هم دارند. اما قبل از هر چیز این سؤال مطرح می‌شود که چرا نیاز به رعایت متد خاصی در توسعه نرم‌افزار است؟

حتماً برای شما به عنوان یک توسعه دهنده پیش آماده که بعد از چند ماه از اجرای پروژه، باید امکاناتی را به پروژه اضافه می‌کردید، و یا شاید در طول استفاده از پروژه‌ی تولید شده، باگ‌هایی گزارش شده که باید رفع می‌گشتند. در این صورت به سورس پروژه خود رجوع کرده و سعی در رفع ایرادات و یا اضافه کردن امکانات جدید می‌کنید. اما اتفاقی که به احتمال زیاد در این شرایط رخ می‌دهد این است که با انبوهی از کدهای ساختار شکن و بی‌نظم مواجه می‌شوید که شما را سر در گم می‌کند. از خود می‌پرسید «آیا واقعاً من این کد را نوشتم؟» و یا «این قطعه کد چه کار می‌کند؟»، «کدام خروجی از برنامه را هندل می‌کند؟»

این مسئله ایست که برای خیلی از توسعه‌دهندگان پیش می‌آید و یکی از دلایل مستندسازی، پروژه برای مواجه با شرایط این چنینی است. در حوزه فرانت‌اند نیز همین شرایط پیش خواهد آمد. اگر HTML و CSS را جزء زبان‌های نشانه‌گذاری بدانیم، با انبوهی از کدها روبه‌رو هستیم که شبیه به هم هستند و با نگاه کردن به آن‌ها نمی‌توان درک کرد چه خروجی‌ای تولید می‌کنند. با توجه به این موضوع چطور می‌توانیم کدهای خود را به طور مداوم توسعه دهیم؟ بعضی از مشکلاتی که در توسعه فرانت‌اند می‌توان نام برد به این قرار است:

• تکرار کردن کدهای روتین و معمول
• تکرار پیشوندهای مرورگرها
• عدم پایبندی به درج کامنت‌ها
• استفاده از سلکتورهای بیش از حد
• وجود ضعف در نام‌گذاری کلاس‌ها

هدف ما از آشنایی با متدولوژی‌های توسعه فرانت‌اند و یادگیری آن‌ها تولید کدهایی است که سه خصوصیت زیر را داشته باشند:

۱- قابلیت خوانایی بالا
۲- قابلیت نگهداشت بالا
۳- قابلیت استفاده مجدد از کدها

رسیدن به این اهداف به طرز فکر ما نسبت به توسعه مرتبط است. قبل از هر چیز باید گفت اگر تا به الان، برای هر قسمت از صفحه وب خود یک کلاس نام‌گذاری می‌کرید و تمام استایل‌ها، انیمیشن‌ها و اسکریپت‌های مورد نیاز را در آن کلاسِ خاص مدیریت می‌کردید، نیاز است تا طرز فکر خود را نسبت به توسعه عوض کنید. مسئله بعدی این است که هرچند خلق و رعایت متدولوژی‌ها یک طرز فکر است، اما ابزارهای مورد استفاده در توسعه فرانت‌اند نیز در رسیدن به هدف می‌توانند برای ما مفید باشند. پیش پردازنده‌هایی مانند Sass یا LESS ، تسک‌رانرهایی مانند Gulp یا Grunt و غیره از این موارد هستند.

راه‌کارهای عمومی
در ابتدا شاید بد نباشد به چند راه حل عمومی و ساده برای بهتر کردن کدهای خود نگاهی کنیم. بخش زیادی از سردرگمی‌های ما در مراجعه مجدد به کد، با کامنت گذاری‌های مناسب در قطعه کدها حل می‌شود. پس چه بهتر که به نوشتن کامنت‌ها عادت کنیم. راه حل بعدی که باید به آن توجه کرد شکستن هر قطعه به قطعات کوچکتر و نظم‌ دادن به آن‌هاست. بهتر است به جای اینکه یک فایل استایل شیت بزرگ داشته باشیم، آن را به چند فایل کوچکتر بشکنیم و هر بخش از کدهای مرتبط با هم را در یک فایل قرار دهیم. مسئله بعدی سعی در استفاده مجدد از کدهایی است که قبلاً نوشتیم. چگونه؟ با استفاده از نام‌گذاری‌های مناسب برای کلاس‌ها و متغیرها و سعی در بهره بردن از پیش‌پردازنده‌ها. چرا که در آن‌ها می‌توانیم توابع و میکسین‌هایی بنویسیم و در جاهای متعدد از آن‌ها استفاده کنیم. اما حالا که کدهای خود را به چند قطعه کوچکتر شکسته‌ایم، حالا که می‌خواهیم استایل‌شیت‌ها را با سینتکس متفاوت بنویسیم، تکلیف کدهای خروجی چیست؟ در اینجا تسک‌رانرها می‌توانند به ما کمک کنند. برای شکستن یک فایل استایل‌شیت به فایل‌های کوچک‌تر، می‌توان ساختار ابتدایی زیر را در نظر داشت:

• color
• typography
• grid/layout
• reset
• base
• forms
• tables
• navigation
• components

اما باید به یاد داشته باشیم که فقط شکستن یک فایل به فایل‌های کوچکتر ملاک نیست، بلکه هدف ما کپسوله کردن کدهای هر بخش و نوشتن کدهای ساخت‌یافته است. در ادامه بیشتر با این مفهوم آشنا می‌شویم. نام‌گذاری فایل‌ها و متغیرها نیز از مواردی است که باید به آن توجه کرد. شاید شما هم در نام‌گذاری متغیرها قرارداد زیر را لحاظ می‌کنید.

/* Background Colors */ 
$background:
$background-header:
$background-content:

/* Colors */
$heading-color:
$link-color:

/* Sizes */
$header-height:
$footer-height:

با این حال من شیوه نام‌گذاری زیر را پیشنهاد می‌کنم:

/* Background Colors */ 
$color-bg:
$color-bg-header:
$color-bg-content:

/* Colors */
$color-heading:
$color-link:

/* Sizes */
$height-header:
$height-footer:

حتی شاید بد نباشد از قابلیت Map کردن در پیش پردازنده‌ها استفاده کرد:

/* Colors */
$colors = {
  bg: value,
  bg-header: value,
  bg-content: value,
  heading: value,
  link: value
};

$color-bg-content = map-get($colors, bg-content);

بنابراین اگر دقت کنید خواهید دید در مسیری حرکت می‌کنیم که در نهایت، کدهای توسعه از کدهای توزیع نهایی متفاوت خواهد بود. ما می‌خواهیم کدهای توسعه قابلیت خوانایی و استفاده‌ مجدد داشته باشد، در حالی که کدهای توزیع نهایی باید تا حد امکان بهینه و کم حجم باشد. به این ترتیب تیم توسعه می‌تواند با کدهای تمیز سر به کار داشته باشد.

همچنین به یاد داشته باشیم که در حین نوشتن استایل‌ها ترتیب پراپرتی‌ها را رعایت کنیم. بعضی از توسعه‌دهندگان پراپرتی‌ها را بر اساس حروف الفبا دسته بندی می‌کنند در حالی که بعضی دیگر طول عنوان و مقدار پراپرتی‌ها را معیار ترتیب در نظر می‌گیرند بعضی دیگر ترتیب‌ها را با توجه به دسته‌بندی نوع پراپرتی‌ها رعایت می‌کنند در حالی که عده‌ زیادی نیز هستند که ترتیب خاصی را رعایت نمی‌کنند. به نظر می‌رسد مرتب‌سازی پراپرتی‌ها بر اساس دسته‌بندی نوع آن‌ها مناسب‌ترین روش است. هر چند همانطور که در گراف زیر می‌بینید این روش محبوب‌ترین هم هستند.

graph

لزوم استفاده از متدولوژی‌ها
بد نیست بدانیم نوشتن کدهای تمیز برای مشارکت در پروژه‌های تیمی امتیازی مثبت محسوب می‌شود. حالا که صحبت از کار تیمی شد، باید توجه کنیم برای انجام کارهای تیمی نیاز به پیروی از یک قرارداد یا Convention خاص است. این قرار داد می‌تواند یکی از متدولوژی‌های موجود باشد، و یا ترکیبی از آن‌ها، و یا حتی قردادی که توسط اعضای تیم خلق می‌شود و همگی بر روی آن اتفاق نظر دارند. رعایت استانداردهای مطرح شده در متدولوژی‌های انتخابی، باعث می‌شود در نهایت کدهایی تمیزتر با قابلیت خوانایی و نگهداشت بالا تولید کنیم. یکی از مزیت‌های استفاده از متدولوژی‌های موجود در این است که با اضافه شدن افراد جدید به تیم، می‌توان توقع داشت که با متد مورد استفاده شما آشنا هستند. راستی، اگر شما جزء آن دسته از افرادی هستید که در تیم خود متدولوژی معتبری استفاده نمی‌کنید، در مواجه با ورود افراد جدید به تیم خود چگونه عمل می‌کنید؟ اگر شما توسعه‌دهنده‌ای هستید که با متدولوژی‌ها آشنا نیست و قرار است به زودی به تیمی حرفه‌ای‌تر بپیوندد که از قضا در آنجا استانداردها رعایت می‌شود، چگونه با این چالش روبرو می‌شوید؟

از طرفی، دیگر طراحی بخش به بخش صفحات وب که از بالا به پایین انجام می‌شدند، منسوخ شده است. با این تفاسیر لزوم آشنا شدن و یادگیری این متدولوژی‌ها بیشتر احساس می‌شود. در حالی که در دنیای امروز باید در طراحی صفحات وب و وب اپلیکیشن‌ها به دنبال طراحی سیستمی از کامپوننت‌ها باشیم. در نتیجه، نرم‌افزار تولیدی، مجموعه‌ای از کامپوننت‌ها خواهد بود که هر کدام از آن‌ها را می‌توان به راحتی اضافه کرد، حذف کرد و یا تغییر داد. 

MaintanableCSS
متد MaintanableCSS در واقع کتابچه‌ای آنلاین است شامل باید‌ها و نبایدهایی که بهتر است در استایل‌نویسی آن‌ها را مد نظر داشت. در این متد به کدنویسی معنایی توجه ویژه‌ای شده است.  اجازه دهید مثالی از قطعه کدی که مورد تأیید این متد نیست را ببینم.


همانطور که می‌بینیدنام‌گذاری کلاس‌ها در تگ‌های HTML ما را به یاد فریم‌ورک بوتسترپ می‌اندازد. اما از نظر این متد، مشکلی که در اینجا وجود دارد این است که شما با نگاه کردن به کد نمی‌توانید متوجه شوید که هر کدام از بخش‌های کد چه چیزی را ارائه می‌دهند. هر چند این‌ها نام‌گذاری‌هایی است که از طرف فریمورک بوتسترپ ارائه شده، اما نمی‌توان تمام تقصیر را به گردن آن‌ها انداخت. در این شرایط می‌توان از نام‌های موجود بهتر استفاده کرد.

عموماً نام‌گذاری از مهمترین اصول مورد توجه متدولوژی‌ها است. دو دیدگاه کلی برای نام‌گذاری کلاس‌ها وجود دارد:
۱- عنصری که از کلاس مورد نظر استفاده می‌کند، چه شکلی خواهد بود؟
۲- عنصری که از کلاس مورد نظر استفاده می‌کند، چه چیزی خواهد بود؟

هرچند نام‌گذاری روش اول معمول‌تر است، اما بهتر است با دیدگاه دوم، کلاس‌ها را نام‌گذاری کرد و از آن‌ها استفاده کرد. از نظر این متد، ماهیت عناصر از ظاهر آن‌ها مهم‌تر است. با این تفاسیر نگاهی به قطعه کدی که مورد تأیید است می‌اندازیم.


چرا این روش پیشنهاد می‌شود؟ چون درک کلاس‌های معنایی آسان‌تر است. در هنگام طراحی ریسپانسیو و استایل‌نویسی مجدد این کلاس‌ها در مدیاکوئری‌ها، پیدا کردن آن‌ها راحت‌تر است. استاندارد‌ها این روش را توصیه می‌کنند برای مثال تگ‌هایی که در HTML5 معرفی شدند را به یاد بیاورید.

متد MaintanableCSS چندان موافق استفاده مجدد از کدها نیست. هرچند در تعریف کدها با قابلیت استفاده مجدد نیز متفاوت از عموم عمل می‌کند که البته تعریف صحیحی را ارائه می‌دهد. این متد می‌گوید کدهای DRY به این معنی نیست که یک چیز ضرورتاً دو بار تکرار نشود. بلکه توجه بیش از حد به کدنویسی DRY نتیجه عکس دارد.

البته تا حدودی درست هم می‌گوید، در شرایطی اگر بخواهیم کلاس‌ها را طوری ایجاد کنیم که نیاز به بازنویسی آن‌ها نباشد و نام‌گذاری‌ای برای آن‌ها در نظر بگیریم که در جاهای متفاوت بتوانیم از آن استفاده کنیم، ساختار کدنویسی معنایی ما شکسته می‌شود؛ چرا که ناچاریم کلاس‌های متعددی ایجاد کنیم و برای ساخت یک کامپوننت هم مجبور می‌شویم از تعداد زیادی کلاس استفاده کنیم در حالی که استفاده از این کلاس‌های متعدد کار را برای ما سخت می‌کند. شاید بوتسترپ هم به دلیل تأکید بیش از حد نسبت به استفاده مجدد، نام‌گذاری مورد تأیید این متد را لحاظ نکرده بود. این را هم فراموش نکنیم که ماهیت فریمورک در ارائه قابلیت‌های استفاده مجدد است. اما یکی از اهداف ما هم استفاده مجدد است. چه باید کرد؟ در ادامه متدهایی را بررسی می‌کنیم که پیشنهاداتی در این مورد دارند. از طرفی استفاده از میکسین‌ها در پیش‌پردازنده‌ها نیز به ما قابلیت استفاده مجدد از کدها را می‌دهد.

متد مورد بحث، استفاده از IDها در در استایل نویسی پیشنهاد نمی‌کند، چرا که آن‌ها بالاترین الویت در اجرا را دارند و قابل رونویسی نیستند.پس بهتر است از IDها در جای مناسب خود استفاده کرد، و نه در استایل‌نویسی. مسئله بعدی لحاظ کردن یک قرارداد منعطف در نام‌گذاری کلاس‌ها است. قرارداد مورد تأیید MaintanableCSS به این صورت است.

/* Square brackets denote optional parts */
.moduleName[-componentName][-state] {}

اجباری در لحاظ کردن نام‌گذاری برای کامپوننت‌ها و وضعیت‌ها نیست، چرا که استایل‌نویسی برای یک ماژول می‌تواند مجزا از استایل‌نویسی برای کامپوننت آن ماژول باشد. در واقع کپسوله سازی به این طریق انجام می‌شود. اما یک ماژول چیست؟ ماژول واحد مستقل و متمایزی است که در کنار دیگر ماژول‌ها می‌تواند ساختار پیچیده‌ای ارائه کند. برای مثال یک اتاق را در نظر بگیرید، تلوزیون یک ماژول از اتاق است. کاناپه نیز همینطور. میز و صندلی نیز به همین صورت.

کامپوننت چیست؟ هر ماژول از چند کامپوننت تشکیل شده است. به عنوان مثال یک ماژول فرم ثبت‌نام، از کامپوننتهایی که تکست فیلد، چک‌باکس و دکمه هستند تشکیل شده است. از طرف دیگر رابط‌های کاربری وضعیت‌های متفاوتی می‌توانند به خود بگیرند. فرض کنید ماژول سبد خرید که می‌تواند وضعیت پر یا خالی بودن را به خود بگیرد، و یا کامپوننت دکمه‌ای که وضعیت فعال یا غیر فعال را به خود می‌گیرد. با این تفاسیر نگاهی به استایل‌نویسی با در نظر گرفتن این قراردادها که گفته شد می‌اندازیم.

/* module container root */
.searchResults {}

/* components of a module */
.searchResults-heading {}

.searchResults-item {}

/* state: such as AJAX loading */
.searchResults-isLoading {}

در این بین کلاس‌های ویرایشگر یا Modifier نیز وجود دارند که قابلیت رونویسی و اضافه کردن پراپرتی‌های جدید را به دیگر استایل‌ها را بر عهده دارند. ویرایشگرها در اکثر متدولوژی‌ها لحاظ شده اند.

SMACSS
سمکس(با تلفظ smacks)  که مخفف Scalable and Modular Architecture for CSS است هم به مانند MaintainableCSS مجموعه‌ای از گاید‌لاین‌ها است که به ما کمک می‌کند تا کد بهتری در CSS تولید کنیم. سمکس نه ابزاری برای توسعه است و نه قوانین سختگیرانه‌ای که باعث هراس توسعه‌دهندگان شود. بلکه راهنمایی منعطف است که با مد نظر داشتن آنها می‌توان کدهایی تولید کرد که ساخت‌یافته باشند. سمکس به بسیاری از جنبه‌ها از جمله ساختاربندی پروژه، نام‌گذاری کلاس‌ها و شیوه نوشتن کدها پرداخته است. بخش اعظمی از محتوای این داکیومنت به رایگان در دسترس است در حالی که برای خواندن محتوای کامل باید مبلغی را پرداخت کرد.

اگر بخواهیم نگاهی کلی به پیشنهادات سمکس داشته باشیم، بهتر است که با ساختاربندی پروژه شروع کنیم. این متد هسته پروژه را در پنج دسته تقسیم‌بندی کرده و با تعاریف و مثال‌هایی از قطعه کدهای کاربردی سعی دارد تا مفاهیم لازم را به مخاطبین انتقال دهد. این پنج دسته به این قرار هستند.

• Base
• Layout
• Module
•State
• Theme

قوانین Base شامل تعریفات اولیه هستند، به عنوان مثال تعریف فونت و سایز متن برای پروژه، پیش‌فرض‌هایی که برای فرم‌ها در نظر گرفته می‌شوند، رنگ لینک‌ها و هاور لینک‌ها و قوانین پایه‌ای دیگر نیز از این جمله هستند. حتی قطعه کدهایی برای ریست کردن استایل‌ها را نیز می‌توان جزء این دسته‌بندی در نظر گرفت.

قوانین Layout برای بخش‌بندی صفحه به اجزای کوچکتر در نظر گرفته می‌شود. تعریف مختصات و مکان نمایش هدر و فوتر از این دست از قوانین هستند. layoutها مکانی هستند که ماژول‌ها در آن قرار می‌گیرند. قطعه کدهایی که ساختار گرید سیستم را پیاده می‌کنند نیز در این دسته از قوانین طبقه‌بندی می‌شوند.

قوانین Module شامل تعریف بخش‌هایی از طراحی هستند که احتمال استفاده مجدد آن‌ها وجود دارد. لیست‌ محصولات، اسلایدر‌ها، فرم ورود و ثبت نام و غیره نمونه‌هایی از ماژول‌های پروژه هستند.

قوانین Satet راهی هستند برای تشریح چگونگی نمایش ماژول‌ها و لی‌اوت‌ها در یک state خاص. به عنوان مثلاً فرض کنید یک دکمه را به عنوان ماژول طراحی کرده‌ایم. این دکمه می‌تواند در وضعیت فعال و یا غیر فعال نمایش داده شود. می‌تواند دکمه حذف کالا و یا اضافه کردن کالا به سبد خرید باشد.

وجود قوانین Theme برای تمام پروژه‌ها لازم و ضروری نیست، بلکه بسته به ماهیت پروژه می‌توان از آن استفاده کرد. تم موجود در سرویس‌های جیمیل و یا یاهو میل را در نظر بگیرید. شما به عنوان یک کاربر، می‌توانید با اعمال تنظیمات خاص قالب جدیدی برای صفحه ایمیل خود اعمال کنید. این نقطه‌ای است که قوانین theme به کمک توسعه‌دهنده‌ها می‌آید. در واقع قوانین تم می‌تواند تمام کدهای بخش‌های فوق را بازنویسی کند.

در کنار تعریف ساختار فوق، میتوان از قوانین نام‌گذاری‌ای که سمکس پیشنهاد کرده نیز پیروی کرد. به عنوان مثال استفاده از پیشوند‌هایی مانند -l و یا -grid برای لی‌اوت‌ها از این دست از قوانین هستند. توسعه دهندگان بسته به قوانینی که در نظر می‌گیرند می‌توانند مستندسازی خاص خود را داشته باشند. این توضیحات ترسیمی از آن چیزیست که سمکس برای توسعه‌دهنده به ارمغان می‌آورد.

ITCSS
این متدولوژی که حالت کوتاه شده‌ Inverted Triangle CSS است، در واقع معماری ایست که پروژه را در ۷ طبقه دسته بندی کرده و این طبقات را در یک مثلث وارونه جای داده.

itcss

همانطور که در شکل می‌بینید، کدهای Settings روی پهنه‌ی بیشتری از DOM تأثیر می‌گذارید در حالی که هر چه به سطوح پایینی نزدیک میشویم از وسعت تأثیر گذاری کمتر شده و روی ویژگی‌های خاص متمرکز می‌شویم. به این ترتیب ITCSS را میتوان یک معماری ۷ لایه دانست که به ساختار پروژه ما نظم می‌دهد. بهتر است نگاهی عمیق‌تر به این لایه‌ها داشته باشیم.

لایه Settings جایی است که اگر از پیش پردازنده‌ها استفاده کنیم، به کار خواهد آمد. تنظیمات عمومی پروژه در این لایه تعریف می‌شود. آنچه مهم است عمومی بودن این تنظیمات است، چرا که قرار است این لایه روی تمام المان‌های پروژه تأثیر بگذارد. از نمونه‌هایی که در این لایه جای دارند می‌توان به سایز قلم، پالت رنگ‌ها و مقادیر کانفیگ‌های پروژه اشاره کرد.

لایه‌ Tools جایی است که ابزارها در آن قرار دارد. این ابزارها می‌تواند در سرتاسر پروژه(به جز لایه تنظیمات) به کار آید. توابع و میکسین‌هایی که به صورت عمومی مورد نیاز است از جمله کدهایی هستند که در این لایه جای دارند. لازم است به این مورد توجه داشته باشیم که میکسین‌ها و توابعی که کاربرد عمومی ندارند بهتر است به صورت جزئی در همان بخشی که مورد نیاز است، نوشته شود.

لایه Generic اولین لایه‌ای است که CSS تولید می‌کند. این لایه به ندرت ویرایش می‌شود و در اکثر پروژه‌ها یکسان باقی می‌ماند. این لایه شامل کدهایی برای یکسان سازی خصوصیات المان‌ها است، یعنی جایی که شما از کدهای ریست استفاده می‌کنید.

لایه Elements جاییست که در آن به المان‌های HTML که فاقد کلاس هستند، شکل اولیه داده می‌شود. تگ‌های سری h و یا تگ‌های a در وضعیت‌های متفاوت در این لایه شکل می‌گیرند.استایل اولیه‌ای که ما برای فیلد‌های فرم، دکمه‌ها، جداول و غیره در نظر داریم باید در این لایه سازماندهی شود. اگر سورس‌های Sass فریمورکی مانند بوتسترپ را دیده باشید، فایل scafolding را می‌توان به عنوان یکی از فایل‌های لایه Elements دانست.

آن دسته از توسعه‌دهندگانی که با متدولوژی OOCSS آشنا هستند با مفهوم آبجکت‌ها در فرانت‌اند نیز آشنا هستند. این لایه اولین لایه‌ای است که در آن کلاس‌های CSS تولید می‌شود. در اینجا ما به آبجکت‌ها استایل مورد نظر را اعمال می‌کنیم. به عنوان مثال کلاس .wrapper یک آبجکت در نظر گرفته می‌شود. کلاس‌هایی که برای استفاده از گرید سیستم‌ها در نظر گرفته شده را نیز می‌توان به عنوان آبجکت دانست.

و بلاخره لایه Components محلی برای نوشتن کدهایی است که به بخش‌های رابط کاربری رنگ و لعاب می‌بخشد. در این لایه به جزئیات طرح توجه می‌شود. این جزئیات بر بخش کوچکی از DOM اثر خواهد گذاشت، چرا که می‌خواهیم به کامپوننت‌های صفحه، شکل و ظاهر مناسب را اعمال کنیم و این کامپوننت‌ها در بخش‌های معدودی از طرح استفاده شده‌اند.

آخرین لایه که Trumps نام دارد. ویرایشگرها و کلاس‌های helper را می‌توان در این لایه دسته‌بندی کرد، چرا که این لایه از الویتی بالاتر از دیگر لایه‌ها برخوردار هست و توانایی رونویسی پراپرتی‌ها را دارد. به همین دلیل منطقی بنظر می‌رسد که از مقدار !important در استایل‌نویسی در این لایه استفاده کنیم.

در این معماری هر لایه شامل چند جزء است که میتوان این اجزا را به صورت زیر نام گذاری کرد.

_. .scss

/* for example */
_settings.colors.scss
_elements.headings.scss
_components.tabs.scss

و در نهایت به کمک این متدولوژی می‌توانیم ساختاری منعطف برای پروژه خود طراحی کنیم که بسیاری از نیازمندی‌هایمان را در آن در نظر گرفته باشیم.

OOCSS
حتماً با مفهوم شئ‌گرایی در برنامه نویسی آشنا هستید یا حداقل اسم آن را شنیدید. شئ‌گرایی یک الگوی برنامه‌نویسی است و برای شکستن کارهای بزرگ به چند کار کوچک استفاده می‌شود. وقتی این مفهوم به دنیای استایل‌شیت‌ها وارد می‌شود آن را OOCSS و یا همان Object Oriented CSS می‌نامیم. مفهوم اصلی در این متدولوژی جداسازی ساختار عناصر، از استایل ظاهری آن‌هاست. به این ترتیب نتیجه این کپسوله‌سازی این خواهد بود که می‌توانیم بدون پیاده‌سازی مجدد عناصر، از آن‌ها در قطعات مختلف کد استفاده‌ مجدد کنیم که باعث می‌شود سرعت توسعه افزایش پیدا کرده و حجم کد تولیدی کاهش یافته باشد.

ساختار عناصر را می‌توانیم به عنوان اسکلت آن‌ها در نظر بگیریم. در اینجا ما بیشتر با مفاهیم باکس مدل و لی‌اوت‌ها سر به کار داریم و به این ترتیب فریم‌هایی بوجود می‌آوریم که می‌توانیم از آن‌ها به عنوان آبجکت استفاده کنیم. این آبجکت‌ها خالی از هرگونه استایل‌های بصری هستند. در مرحله بعد می‌توانیم به صورت اختیاری هر پوسته‌ی ظاهری که خواستیم را ایجاد و روی این آبجکت‌ها اعمال کنیم. به مثال زیر توجه کنید.

/* A simple, design-free button object. Extend this object with a `.btn--*` skin class. */
.btn {
    display: inline-block;
    padding: 1em 2em;
    vertical-align: middle;
}

/* Positive buttons skin. Extends `.btn`. */
.btn--positive {
    background-color: green;
    color: white;
}

/* Negative buttons skin. Extends `.btn`. */
.btn--negative {
    background-color: red;
    color: white;
}

در اینجا یک کلاس btn. می‌بینید که ساختار عنصر مورد نظر را طرح ریزی کرده است. اما هیچ رنگ و لعابی ندارد. در قدم بعدی کلاس btn–positive. را به عنصر مورد نظر اعمال می‌کنیم تا به آن طرحی که میخواستیم برسیم. ما می‌توانیم انبوهی از این استایل‌های بصری را داشته باشیم و از هر کدام، در هر دکمه‌ای که نیاز بود استفاده کنیم. حتی می‌توانیم یکی از این استایل‌ها را به عنوان استایل پیش‌فرض برای آبجکت مورد نظر لحاظ کنیم. این درک و مفهومی است که بسیاری از فریمورک‌های فرانت‌اند نیز از آن استفاده می‌کنند.

BEM
BEM نیز یکی دیگر از متدولوژی‌های توسعه فرانت‌اند است که می‌توان از آن به عنوان یه متدولوژی کامل نام برد. چیزی که توجه ما را در این متد جلب می‌کند استراتژی نام‌گذاری است. با استفاده از این استراتژی می‌توانیم کلاس‌ها را به سه گروه کلی تقسیم کنیم:

• بلاک(‌Block): ریشه و پایه کامپوننت
• عنصر(Element): کامپوننتی که خود درون بلاک قرار دارد
• پیراینده(Modifier): تغییر یا گسترش بلاک

یک قیاس از سه گروه بالا را در این بخش می‌توان دید که عناصر با دوتا زیر خط(__) و پیراینده‌ها با دوتا خط تیره(-‌-) از  بلاک اصلی متمایز می‌شوند.

.dog { }
.dog__tail { }
.dog--small { }

در قیاس فوق، ما dog. را به عنوان یه بلاک می‌بینیم که اساس کامپوننت ما به حساب می‌آید. سپس dog__tail.(دُم سگ) یک عنصر است و در واقع بخشی از کامپوننت اصلی ما(سگ) محسوب می‌شود، که البته خودش یک کامپوننت کوچک‌تر هست. و در نهایت dog-‌-small. یک پیراینده برای بلاکِ سگ است. ما حتی میتوانیم برای عناصر هم پیراینده داشته باشیم. به عنوان مثال dog__tail-‌-short. یک تغییر ظاهری برای دم سگ ایجاد می‌کند.

در کنار موارد گفته شده، در خیلی از مواقع ما قصد داریم برای بلاک‌های خود از نام‌هایی شامل دو کلمه استفاده کنیم. در این صورت و شرایط مشابه، از یک خط تیره برای جدا کردن کلمات استفاده می‌کنیم و البته باید یادمان باشد که کلاس‌ها با حروف کوچک نوشته می‌شوند. در نهایت به کمک این متدولوژی می‌توانیم جنبه‌های مختلفی از کامپوننت‌ها را کپسوله کنیم. شاید بد نباشد اگر یک مثال از عناصری که می‌توانند در صفحه وب وجود داشته باشند هم ذکر کنیم تا کپسوله سازی را راحت‌تر درک کنیم:

/* Block component */
.btn {}

/* Element that depends upon the block */ 
.btn__price {}

/* Modifier that changes the style of the block */
.btn--orange {} 
.btn--big {}

CSS Modules
متدولوژی ماژول‌‌های CSS آخرین متدی است که این روزها در ترندها مشاهده می‌کنیم. این متدولوژی به ما امکان پیاده‌سازی ماژول‌ها و کامپوننت‌هایی را می‌دهد که حقیقتاً می‌توانیم نام ماژول را به آن‌ها بدهیم. اجازه دهید تشریح کنیم که این متد با متدهایی که تا اینجا گفته شد چه تفاوتی دارد. متدهایی که تا اینجا با آن‌ها آشنا شدیم همگی سعی در کپسوله کردن کدها و عناصر صفحات ما داشتند. این کپسوله‌سازی به کمک قراردادهای نام‌گذاری کلاس‌ها انجام می‌شد تمام سعی ما بر این بود که کلاس‌هایی با نام‌های متفاوت و منحصر به فرد ایجاد کنیم که هم گویای این مطلب باشد که این کلاس به چه عنصری اشاره دارد و هم پیرو قواعد و قانونی منظم جهت نام‌گذاری باشد.

از طرفی بعد از نام‌گذاری کلاس‌ها و استفاده از آن‌ها در HTML، کامپایلی صورت نمی‌گیرد و مرورگر میداند کدهای کدام کلاس را روی کدام عنصر اعمال کند. حالا فرض کنید در طرحی ماژول سبد خرید دارید. در همین طرح ماژول لیست محصولات هم دارید. هر دوی این ماژول‌ها برای خود عنوان نیز دارند. بنظر شما عالی نمی‌شد اگر برای عنوان هر دوی این ماژول‌ها، دو کلاس متفاوت با نام یکسانِ .title می‌نوشتید و مرورگر این توانایی را داشت که بدون سردرگمی، کلاس مورد نظر را بر عنصر مورد نظر اعمال کند؟

خب این قابلیت در متدولوژی ماژول‌های CSS وجود دارد. شما می‌توانید برای هر ماژول کلاسی با هر نامی را آزادانه اختیار کنید و توجهی به این موضوع نداشته باشید که آیا این کلاس در ماژول‌های دیگر هم وجود دارد یا نه. شاید با خود می‌پرسید پس مرورگر چطور بین کلاس‌ها تمایز قائل می‌شود؟ تمام این‌ها به کمک جاواسکریپت و کامپایلر‌هایی که استفاده خواهیم کرد، میسر خواهد بود.

به لطف نسل جدید جاواسکریپت و امکان مدیریت ماژول‌ها در آن، ما میتوانیم برای DOM مجازی‌ای که ساخته‌ایم، ماژول‌های CSS داشته باشیم. اجازه دهید به کمک یک مثال بهتر با این مفهوم آشنا شویم.

import styles from "./styles.css";

element.innerHTML = “

An example heading

”;

همانطور که می‌بینید، در قطعه کد بالا، فایل استایل‌شیت به عنوان یک ماژول در اسکریپت وارد شده که از طریق نام مستعاری که به آن نسبت داده شده، می‌توان به کلاس‌های این ماژول CSS دسترسی داشت. این قطعه کد پس از کامپایل باعث تغییراتی در فایل استایل‌شیت و HTML خواهد شد که نمونه‌ای از این تغییرات را در ادامه خواهید دید.

._styles__title_309571057 {
  background-color: red;
}

An example heading

کد نهایی پس از کامپایل به این صورت خواهد بود که دیدید. شاید با خود بگویید این کامپایل چگونه و با چه ابزارهایی انجام ‌می‌شود. به لطف ابزارهایی همچون Webpack و یا Browserify می‌توانیم به این متدولوژی دست یابیم. اگر برای اجرای آن نگران هستید، می‌توانید از ریپازیتوری‌ای که به این منظور آماده کرده‌ام کمک بگیرید. بخش کلیدی از تنظیمات لودر استایل‌شیت در Webpack که باعث می‌شود آن‌ها را به صورت ماژول داشته باشیم را در زیر میبینیم،‌ هرچند استایل‌شیت‌ها را با سینتکس پیش‌پردازنده‌ها نیز می‌توان به صورت ماژول لود کرد.

{
  test: /\.css/,
  loader: ExtractTextPlugin.extract('css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]'),
}

شاید از خود بپرسید آیا زحمت تولید DOM در جاواسکریپت برای استفاده از ماژول‌های CSS ارزش دارد یا خیر؟ باید گفت هرچند بسیاری از توسعه‌دهنگان پلاگین‌های جاواسکریپتی، این زحمت را متقبل می‌شوند، اما نیازی نیست شما حتماً به این منوال دام مجازی درست کنید.

امروز استفاده از React در وب‌سایت‌ها و وب‌اپلیکیشن‌ها رو به افزایش است و دیگر تولید DOM مجازی به آن سختی‌های سابق نیست. چرا که به کمک React می‌توان به معنی کلمه کامپوننت نوشت و چه بهتر که این کامپوننت‌ها استایل مربوط به خود را داشته باشد. استایلی شامل کلاس‌هایی که فقط به صورت محلی برای آن کامپوننت مورد نظر، معتبر است. بنابراین ما برای جاواسکریپتی خاص که DOM تولید می‌کند، استایل اختصاصی می‌نویسیم و مهم نیست با چه استراتژی‌ای از کانفلیکت نام‌گذاری کلاس‌ها اجتناب می‌کنیم. چرا که کانفیلکتی اتفاق نمی‌افتد. به این ترتیب نیاز به متدولوژی BEM نیز کمتر احساس می‌شود  یک نمونه از ساخت DOM در React را میبینیم که از ماژول‌های CSS نیز استفاده می‌کند.

import React from 'react';
import styles from './table.css';

export default class Table extends React.Component {
    render () {
        return (
          
A0
B0
); } }

سپس کامپوننت مورد نظر، بعد از رندر شدن تبدیل به کد زیر می‌شود.

A0
B0

از دیگر امکانات ماژول‌های سی‌اس‌اس می‌توان به پراپرتی composes اشاره کرد که که کاربردش در این است که می‌توان کدهای یک کلاس را در کلاسی دیگر به کار برد. برعکسِ خاصیت Extend کردن در پیش‌پردازنده‌ی Sass ، در این قابلیت، کدها بین کلاس‌ها به اشتراک گذاشته نمی‌شود. بلکه با ایجاد یک گراف نیازمندی‌ها، کامپایلر تشخیص میدهد یک کلاس‌ به چه کلاس‌هایی نیازمند است و هرجا از آن کلاس استفاده شود، از کلاس‌های دیگری که کلاس مورد نظر به آن‌ها نیاز دارد نیز استفاده خواهد شد. به عنوان مثال به قطعه کد زیر توجه کنید.

.base { /* common styles */ }

.normal {
  composes: base;
  color: hsl(210, 61%, 31%);
  background: hsla(210,61%,51%,0.1);
}

.danger {
  composes: base;
  color: hsla(0, 61%, 51%, 0.5);
  background: white;
}

از کلاسی danger به این صورت می‌توان استفاده کرد:


و در نهایت پس از عملیات رندرینگ، کد اچ‌تی‌ام‌ال به صورت زیر تغییر می‌کند.


شاید نگران این باشید که کلاس‌هایی با نام‌های زشت و طولانی ایجاد کرده‌ایم. هرچند می‌توان تنظیمات کامپایل را طوری انجام داد که کلاس‌هایی با نام کوتاه‌تر تولید شود، اما نگرانی برای زشت بودن نام آن‌ها بی‌مورد است. نام کلاس‌ها وجود دارند تا مرورگر بتواند بر اساس آن استایل را اعمال کند. آیا فرقی دارد زشت باشد یا با معنی؟ البته با معنی بودن نام کلاس‌ها برای توسعه‌دهندگان مهم است. اما همانطور که گفتیم کد توسعه‌ی ما از کد توزیع نهایی ما جداست و ما در هنگام توسعه با این کلاس‌های زشت سر به کار نداریم؛ هرچند آنقدرها هم زشت و بی‌معنی نیستند. اما آنچه مهم است کدهای توسعه‌ی ما خواناست و به راحتی قابل استفاده مجدد می‌باشد.

شاید نگران سختی‌های دیباگ کردن کدهای کامپایل شده باشید. این چالشی بود که در مواقع استفاده از پیش‌پردازنده‌ها نیز با آن روبرو بودیم و Source Map در این مواقع به کار ما خواهند آمد. از طرفی هرچند نام کلاس‌ها در این متد غیر قابل پیش‌بینی هستند اما اگر این ماژول‌ها را برای وظایف خاص تعریف کنیم، دیباگ کردن آن‌ها در ابزار توسعه‌دهنده‌گان مرورگر راحت‌تر می‌شود.

شاید با خود بگوید، کلاس‌هایی که می‌نویسید قابل استفاده مجدد نیست. شاید درست بگوید اما فلسفه‌ی این متد در این است که کامپوننتی تولید کنید که قابل استفاده مجدد باشد. هر چند شما می‌توانید کلاس‌های عمومی هم بنویسید و از آن‌ها استفاده مجدد کنید، در ضمن یادتان باشد می‌توانید با پراپرتی composes نیز کلاسی را از یک ماژول سی‌اس‌اس به ماژولی دیگر تزریق کنید.

با توجه به محبوبیت React و Webpack در سال‌های اخیر، این احتمال وجود دارد که اقبال عمومی به این رویکرد روی خوش نشان دهد. چرا که این روش می‌تواند شیوه‌ی استایل‌نویسی ما را تغییر دهد.به خصوص که قرار است در نسخه ۴ از پیش‌پردازنده Sass امکان پشتیبانی از CSS Modules ها ارائه شود.

نتیجه‌گیری
در این مقاله سعی کردیم آن دسته از متدولوژی‌های فرانت‌اند که بیشتر شناخته شده هستند را بررسی کرده باشیم، هرچند هستند متدولوژی‌هایی مانند Atomic Design که مجال صحبت در مورد آن‌ها نبود اما هدف آشنایی با مزایای این متدها و سعی در بهره گرفتن از آن‌ها در طول روند توسعه است. همانطور که قبلاً اشاره شد این متدها وجه اشتراکاتی با یکدیگر دارند و در عین حال تناقضاتی را نیز شامل می‌شوند. اینکه کدام متد برای ما مفیدتر است در حیطه تشخیص خود ماست. چرا که بسته به نوع پروژه و افراد تیم می‌توان از متدهای متفاوتی استفاده کرد. اگر خوب با مفاهیم این متدها آشنا شده باشیم، حتی میتوانیم قراردادهای خاص خود را برای پروژه‌های‌مان تعریف کنیم و این قراردادها را مستندسازی کنیم. شاید کنجکاو باشید که بدانید محبوب‌ترین متد بین توسعه‌دهندگان کدام است، به این منظور می‌توان به نظرسنجی‌ای که مجله اسمشینگ در حساب توییتر خود منتشر کرده بود استناد کرد.

Screen-Shot-2016-03-13-at-12.17.16-PM

هرچند نظرسنجی فوق از حسابی معتبر منتشر شده و تعداد شرکت‌کنندگان آن کم هم نیستند، اما باید این را در نظر گرفت که متد ماژول‌های CSS بسیار جوان است و با توجه به پیشرفتِ امروز دنیای فرانت‌اند، می‌توان آینده روشنی برای آن تجسم کرد و آن را انقلابی در روند توسعه دانست.  پس بد نیست اگر از همین امروز نیم نگاهی به آن داشته باشیم.

آنچه پیروی از متدولوژی‌های فرانت‌اند برای ما به ارمغان می‌آورد نظم در کار است. به این ترتیب پروژه‌ی ما دارای ساختاری قابل توسعه و منعطف خواهد شد، کدهای ما تمیز و مرتب خواهند بود، می‌توان آن‌ها را به راحتی خواند، توسعه داد و از آن‌ها استفاده مجدد کرد. اگر بخواهید بعد از چند ماه به کدهای یکی از پروژه‌تان رجوع کنید، دیگر ترسی از روبرو شدن با آن‌ها نخواهید داشت، چرا که آن‌ها خوانا هستند. اگر عضو جدیدی به تیم شما اضافه شود، به راحتی و در مدت زمان کمتر با پروژه‌های شما آشنا می‌شود. اگر شما به عنوان یک توسعه دهنده بخواهید تیم خود را ترک کنید می‌توانید با خیال راحت این کار را انجام دهید؛ چرا که کدی از خود به جای گذاشته‌اید که بعد از شما هر کسی می‌تواند از آن استفاده کند و آن را توسعه دهد.