Web Components برای ساخت عناصر قابل استفادهٔ مجدد بر پایهٔ قابلیتهای مرورگر به کار میرود. ارزش آن در یک پروژهٔ چندفریمورکی میتواند داشتن قرارداد مشترک برای بخشی از رابط باشد، اما نتیجه به طراحی همان قرارداد وابسته است. نسخهٔ قبلی این مقاله از پشتیبانی کامل همهٔ مرورگرها و بهترین بودن Lit 4.0 حرف میزد. نام نسخه و این نتیجهٔ عمومی پشتوانهٔ مشخصی نداشت و حذف شده است. باید قابلیتهای واقعی و ابزار منتخب را جدا بررسی کرد.
یک Design System فرضی با صفحههای ساختهشده در چند محیط را در نظر بگیرید. اگر همه به یک برچسب وضعیت نیاز دارند، یک عنصر سفارشی کوچک میتواند شکل مشترکی ارائه کند. ولی اگر هر تیم دربارهٔ معنای وضعیت اختلاف دارد، یک فایل مشترک اختلاف را حل نمیکند. پیش از انتخاب فناوری، نام وضعیتها، ورودیها و رفتار خالی را بنویسید. استفادهٔ مجدد موفق از همین مرز معنایی آغاز میشود و صرف یکسان بودن ظاهر کافی نیست.
سه قابلیت با نقشهای متفاوت
Custom Elements اجازه میدهد رفتار یک عنصر سفارشی را تعریف و ثبت کنید. Shadow DOM ساختار داخلی جدا برای نمایش و سبک فراهم میکند. template و slot به ساختار قابل تکرار و ورود محتوای صفحه مربوطاند. بخش Custom Elements در HTML Standard قرارداد استاندارد را توضیح میدهد. این مجموعه یک نسخهٔ کلی ندارد که بتوان پشتیبانی همهٔ جزئیات آن را با عبارت کوتاه «Web Components کامل» بیان کرد.
برای یک component ساده، استفاده از همهٔ قابلیتها الزامی نیست. اگر فقط رفتار روی HTML موجود اضافه میشود، شاید مرز Shadow DOM ضرورت نداشته باشد. اگر برخورد سبکها مسئلهٔ واقعی است، جداسازی میتواند کمک کند. انتخاب باید با مشکل مشخص مرتبط باشد. مخفی کردن هر جزء در یک مرز داخلی، خودبهخود معماری بهتر نمیسازد و ممکن است شخصیسازی یا دسترسی مصرفکننده به ساختار را پیچیده کند.
نمونهٔ مستقل یک برچسب وضعیت
نمونهٔ زیر سه برچسب برای آماده، در حال بررسی و وضعیت نامعلوم دارد. آن را در فایل status-label.html ذخیره کنید و باز کنید. HTML، CSS و JavaScript در همان فایلاند؛ به package، فونت خارجی، تصویر یا API وابسته نیستند. متن هر وضعیت داخل خود عنصر نوشته شده و حتی پیش از تعریف Custom Element نیز در HTML وجود دارد. رنگ، تنها نشانهٔ وضعیت نیست و کاربر از روی متن معنای آن را میفهمد.
<!doctype html>
<html lang="fa" dir="rtl">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>برچسب وضعیت</title>
<style>body{font-family:system-ui;max-width:42rem;margin:2rem auto;padding:1rem;line-height:1.8}</style>
<h1>وضعیت درخواستها</h1>
<p>درخواست نخست: <tara-status state="ready">آماده</tara-status></p>
<p>درخواست دوم: <tara-status state="review">در حال بررسی</tara-status></p>
<p>درخواست سوم: <tara-status state="unknown">وضعیت نامعلوم</tara-status></p>
<script>
class TaraStatus extends HTMLElement {
constructor() {
super();
const root = this.attachShadow({mode:'open'});
root.innerHTML = `<style>
:host{display:inline-block;border-radius:6px;padding:.1rem .5rem;background:#e8eaf0;color:#222}
:host([state="ready"]){background:#e0f3e6;color:#17482b}
:host([state="review"]){background:#fff0cb;color:#684500}
</style><span><slot></slot></span>`;
}
}
customElements.define('tara-status', TaraStatus);
</script>
</html>
نام tara-status دارای خط تیره است و یک عنصر autonomous تعریف میشود. در مثال، ساختار داخلی فقط یک span و slot است. CSS مربوط به حالتها بر اساس attribute روی host عمل میکند و هیچ selector یا class معرفینشدهای لازم ندارد. اگر مقدار state ناشناخته باشد، ظاهر خنثی باقی میماند. این انتخاب fallback آموزشی است؛ برای محصول واقعی باید معلوم باشد مقدار ناشناخته چگونه ثبت و پیگیری میشود و آیا کاربر نیاز به توضیح بیشتری دارد.
برای افزودن حالت جدید، هم معنای متن و هم مقدار state را در قرارداد ثبت کنید. فقط اضافه کردن یک رنگ، نقش حالت را روشن نمیکند. اگر «در حال بررسی» و «نیازمند توجه» برای کاربر اقدام متفاوتی دارند، متن باید این تفاوت را نشان دهد. برچسب مثال تعاملی نیست؛ به آن role دکمه ندادهایم و با کلیک عملیات ندارد. قراردادن رفتار کلیک در چنین عنصر کوچکی باید با نیاز و دسترسپذیری جدا بررسی شود.
مرز سبک را با مرز امنیت اشتباه نگیرید
راهنمای Shadow DOM سازوکار ساختار داخلی و سبک را توضیح میدهد. این مرز برای جلوگیری از برخورد ناخواستهٔ selectorها مفید است، اما راه مخفی کردن دادهٔ محرمانه نیست. اطلاعات حساس نباید به امید دور ماندن از دسترس در DOM داخلی ذخیره شوند. کنترل دسترسی به داده در سرور انجام میشود. حالت closed نیز قرارداد امنیتی جایگزین برای مجوز محصول ایجاد نمیکند.
در طراحی Theme، تصمیم بگیرید کدام مقدار بیرون قابل تغییر باشد. برای برچسب وضعیت، رنگ پسزمینه و متن ممکن است از tokenهای مشترک بیایند. اگر هر مصرفکننده با selectorهای داخلی جزئیات را تغییر دهد، نسخهٔ بعدی component به سختی منتشر میشود. بهتر است سطح شخصیسازی کوچک و مستند بماند. تغییر ساختار span داخلی نباید بدون دلیل به شکستن دهها مصرفکننده منجر شود. سطح عمومی component همان چیزی است که باید پایدار نگه دارید.
Slot محتوا را از ساختار جدا میکند
در نمونه، slot متن نوشتهشده در صفحه را نمایش میدهد. این انتخاب اجازه میدهد نویسندهٔ HTML محتوای وضعیت را کنترل کند و component ساختار نمایش را نگه دارد. راهنمای templates و slots برای این قرارداد مفید است. اگر محتوای ورودی باید محدود باشد، همان محدودیت را تعریف کنید؛ slot بهتنهایی نمیفهمد که محصول فقط متن ساده میخواهد یا ساختار پیچیده نیز مجاز است.
برای componentهای بزرگتر، نام slotها باید به نقش محتوا اشاره کند. عنوان، توضیح و اقدام اصلی با «بخش اول» و «بخش دوم» تفاوت دارند. نام نقش به مصرفکننده کمک میکند هدف ورودی را بفهمد و در تغییر چیدمان نیز معنی خود را حفظ میکند. تعداد زیاد slotها ممکن است نشان دهد component چند مسئولیت متفاوت را جمع کرده است. قبل از گسترش، بررسی کنید آیا تقسیم به دو جزء کوچکتر قرارداد روشنتری ایجاد میکند.
رویدادها باید قرارداد داده داشته باشند
اگر یک component تعاملی رویداد بیرونی ارسال کند، نام و payload آن باید مستند شوند. مصرفکننده باید بداند رویداد بعد از چه کاری رخ میدهد و آیا عمل تجاری واقعاً تمام شده است. رویداد «درخواست ثبت» با «ثبت موفق» فرق دارد. اگر این دو با یک نام ارسال شوند، فرانتاند ممکن است پیش از تأیید سرور پیام موفقیت نشان دهد. فناوری مرورگر قرارداد معنایی رویداد را از نام تابع استخراج نمیکند.
مرز Shadow DOM نیز در مسیر رویدادها اثر دارد و باید با رفتار مورد نیاز هماهنگ شود. لازم نیست هر رویداد داخلی به صفحه نشت کند. برای نمونهٔ برچسب، رویدادی نداریم؛ افزودن event صرفاً برای نمایش امکانات به مثال مسئولیت بیدلیل اضافه میکند. در محصول، فقط چیزی را عمومی کنید که مصرفکننده واقعاً لازم دارد. یک سطح عمومی محدود، تغییرهای داخلی را سادهتر میکند و از وابستگی تصادفی تیمها به جزئیات جلوگیری میکند.
Lit ابزار کمکی است، نه خود استاندارد
مستندات رسمی Lit ابزارهای ساخت component را معرفی میکند. استفاده از آن میتواند برای template و State مناسب باشد، ولی باید dependency و قرارداد نسخه را در پروژه حساب کنید. یک عنصر ساده مثل نمونهٔ این مقاله بدون library هم قابل توضیح است. برای جزء پیچیدهتر، هزینهٔ کد دستی و امکانات ابزار را مقایسه کنید. از نبود library نمیتوان نتیجهٔ برتری گرفت و از وجود آن نیز کیفیت طراحی component ثابت نمیشود.
برای SSR، مسیر رندر و ادامهٔ رفتار سمت کلاینت را با ابزار واقعی بررسی کنید. راهنمای SSR در Lit دامنهٔ راهکار آن را توضیح میدهد. عبارت «Web Components مشکل SSR دارد» بدون نوع component و شکل رندر مبهم است. محتوای ساده، کنترل تعاملی و دادهٔ وابسته به کاربر نیازهای متفاوتی دارند. انتخاب باید با محتوای قابل مشاهده پیش از اجرای JavaScript و قرارداد تعامل بعدی هماهنگ باشد.
استفاده در چند فریمورک به مستند نیاز دارد
داشتن تگ مشترک در HTML، تمام تفاوتهای property، attribute و event را حذف نمیکند. مصرفکنندهٔ هر فریمورک باید بداند ورودی را چگونه میدهد و رویداد را چگونه میگیرد. یک مثال کوتاه برای هر محیط واقعی سازمان از ادعای کلی «Interop کامل» مفیدتر است. اگر تیمها فقط در یک فریمورک کار میکنند، هزینهٔ لایهٔ مشترک را با نیاز واقعی بسنجید. چندمحیطی بودن یک امکان است، نه هدف اجباری همهٔ محصولات.
برای ادامهٔ بررسی سازگاری، مقالهٔ Firefox و Web Components به اصلاح ادعاهای نسخهای میپردازد. در پروژهٔ خود، یک جزء کوچک با قرارداد روشن انتخاب کنید و متن طولانی، مقدار ناشناخته و تغییر Theme را در طراحی آن ببینید. هدف این است که مصرفکننده بتواند با ورودی و خروجی مستند کار کند. آیندهٔ رابط وب با یک ابزار واحد پیشبینی نمیشود؛ کیفیت همین قراردادها ارزش استفادهٔ مجدد را در محصول مشخص میکند.
هنوز دیدگاهی ثبت نشده
اولین نفری باشید که نظر میدهد!