توسعه فرانت‌اند

Micro-frontends: معماری مقیاس‌پذیر فرانت‌اند

Shell، Module Federation و iframe، state و طراحی مشترک، سازگاری انتشار و rollback؛ انتخاب معماری با نیاز واقعی بدون تضمین استقلال.

1404/12/17 1 دقیقه مطالعه 1,214 بازدید

سه تیم روی یک محصول کار می‌کنند، اما هر انتشار باید در صف یک build مشترک بماند. تقسیم فرانت‌اند به بخش‌های مستقل می‌تواند بخشی از این گلوگاه را کم کند، اگر مرز مسئولیت و قرارداد ترکیب روشن باشند. Micro-frontends صرفاً کنار هم گذاشتن چند framework نیست. این معماری درباره مالکیت، انتشار و همکاری بخش‌های محصول تصمیم می‌گیرد و هزینه هماهنگی تازه‌ای هم ایجاد می‌کند.

اندازه شرکت به‌تنهایی دلیل انتخاب یا رد این روش نیست. یک سازمان بزرگ ممکن است با monolith ماژولار خوب کار کند و یک تیم کوچک در شرایط خاص به ترکیب بخش بیرونی نیاز داشته باشد. مسئله را دقیق بنویسید: چه چیزی مستقل تغییر می‌کند، چرا انتشار فعلی مانع است و چه قراردادهایی مشترک می‌مانند؟ واژه «مقیاس‌پذیر» بدون معیار فنی و سازمانی، تصمیم معماری قابل ارزیابی نمی‌سازد.

مرز را از قابلیت محصول بگیرید

مرور Microfrontends در single-spa درباره بخش‌های مستقل و ترکیب آن‌ها توضیح می‌دهد. مرز مناسب معمولاً به حوزه کار مربوط است، نه صرفاً نوع widget. تقسیم دکمه، جدول و فرم میان تیم‌های مستقل می‌تواند یک جریان ساده را به انتشار چند بخش وابسته کند. اگر بخش‌ها همیشه با هم تغییر می‌کنند، استقلال نامی شاید هزینه را بیشتر کرده باشد.

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

Shell و قرارداد ترکیب

Shell می‌تواند route، ساختار اصلی، برخی providerها و محل قرارگیری بخش‌ها را مدیریت کند. این نقش نباید به مخزن همه منطق کسب‌وکار تبدیل شود، وگرنه گلوگاه مشترک دوباره ساخته می‌شود. مشخص کنید بخش مستقل چه ورودی می‌گیرد و چه خروجی یا eventی می‌دهد. نسخه قرارداد، مسیر failure و رفتار mount و unmount باید قابل مشاهده باشند. نام تیم جای API روشن را نمی‌گیرد.

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

Module Federation چه چیزی فراهم می‌کند؟

مستندات Module Federation در webpack اشتراک و مصرف module میان buildهای مستقل را توضیح می‌دهد. این ابزار می‌تواند بخشی از ترکیب runtime را فراهم کند، اما route، امنیت، داده و طراحی مشترک را خودبه‌خود حل نمی‌کند. remote باید با host قرارداد سازگار داشته باشد. منتشر شدن فایل remote به معنی قابل استفاده بودن آن برای همه نسخه‌های host نیست.

اشتراک dependency تصمیم حساس دیگری است. چند نسخه React یا router می‌تواند بر اندازه و رفتار اثر بگذارد؛ اجبار به singleton هم همه ناسازگاری نسخه را برطرف نمی‌کند. سیاست نسخه، محدوده پشتیبانی و rollback باید روشن باشند. اگر هر انتشار به ارتقای اجباری همه تیم‌ها وابسته است، وعده استقلال را دوباره بسنجید. ابزار loader استقلال سازمانی را از قراردادهای ناسازگار استخراج نمی‌کند.

iframe مرز متفاوتی دارد

مرجع iframe در MDN درباره زمینه جدا و ویژگی‌های محدودسازی توضیح می‌دهد. iframe می‌تواند برای بعضی ادغام‌ها مرز مناسبی باشد، ولی ارتفاع، navigation، focus و ارتباط داده نیاز به طراحی دارند. قابلیت sandbox باید با نیاز واقعی تنظیم شود؛ افزودن همه مجوزها مرز مورد انتظار را می‌تواند کم‌اثر کند. origin و سیاست محتوا هم اهمیت دارند.

پیام میان frameها باید با بررسی origin و شکل داده همراه باشد. یک رشته دریافت‌شده نباید بی‌دلیل فرمان برنامه یا HTML خام شود. session و cookie در زمینه‌های متفاوت هم قرارداد یکسانی با اجرای module در صفحه ندارند. اگر تجربه یکپارچه لازم است، هزینه این تفاوت‌ها را پیش از انتخاب حساب کنید. جداسازی قوی‌تر ممکن است هماهنگی تجربه را دشوارتر کند و باید همین trade-off روشن بماند.

ترکیب سرور و مرز مسیر

ترکیب در سرور یا تقسیم بر اساس route می‌تواند برای برخی محصول‌ها ساده‌تر از ادغام چند مؤلفه در یک صفحه باشد. در این روش، هر بخش شاید صفحه کامل خودش را ارائه کند و ناوبری کاربر قرارداد مشترک داشته باشد. مزیت و محدودیت به نیاز انتقال state و سرعت جابه‌جایی مربوط است. یک روش را برای همه دامنه‌ها معرفی نکنید؛ الگوی تغییر و کار مخاطب تعیین‌کننده‌اند.

در SSR، داده خصوصی و cache باید با مرز درخواست هماهنگ باشند. مشترک شدن client یا خروجی میان حساب‌ها ممکن است اطلاعات را مخلوط کند. نتیجه HTML هم باید با قرارداد hydration سازگار باشد. راهنمای Apollo Client درباره عمر cache و هویت داده توضیح دارد. تقسیم فرانت‌اند، مسئولیت نگهداری داده معتبر و خصوصی را حذف نمی‌کند.

طراحی مشترک فقط کتابخانه دکمه نیست

رنگ، spacing، typography و مؤلفه‌ها باید قرارداد داشته باشند، ولی تجربه مشترک به نام کنترل‌ها، خطاها و مسیرها هم وابسته است. اگر هر بخش اعلان متفاوتی بسازد، مخاطب با یک محصول ناهماهنگ روبه‌رو می‌شود. کتابخانه مشترک باید نسخه‌بندی و مسیر ارتقا داشته باشد. وابستگی عمیق همه بخش‌ها به release یک package مشترک هم می‌تواند استقلال را محدود کند.

CSS سراسری می‌تواند ظاهر بخش دیگر را تغییر دهد. Scope کلاس‌ها، tokenها و قواعد reset باید معلوم باشند. تیم‌ها باید بدانند چه چیزی از host می‌آید و چه چیزی در بخش خودشان تعریف می‌شود. Storybook می‌تواند حالت‌های مؤلفه مشترک را مستند کند، ولی وجود آن به معنی یکسان بودن اجرای واقعی همه بخش‌ها نیست. نسخه مصرف‌شده و تنظیم محیط اهمیت دارند.

State مشترک را محدود کنید

برخی داده مانند هویت حساب یا انتخاب سبد به چند بخش مربوط‌اند. مشخص کنید منبع معتبر کجاست و کدام بخش فقط نمایش می‌دهد. اتصال همه قسمت‌ها به یک store عمومی می‌تواند coupling تازه بسازد. event مشترک نیز باید نام، نسخه و shape روشن داشته باشد. اگر رویداد فقط می‌گوید «تغییر شد»، مصرف‌کننده شاید به دریافت‌های بی‌دلیل و فرض‌های نامطمئن وابسته شود.

هماهنگی local state با سرور نیاز به سیاست دارد. خبر فوری در یک بخش ممکن است هنوز نتیجه موقت باشد و بخش دیگر نباید آن را قطعی فرض کند. خطای جزئی نیز باید دامنه اثر را بیان کند. راهنمای اعلان‌ها به هماهنگی پیام و وضعیت کمک می‌کند. ارتباط غیرمستقیم میان تیم‌ها نباید حقیقت نتیجه را در شبکه‌ای از eventهای مبهم پنهان کند.

انتشار مستقل با سازگاری قرارداد

برای deploy مستقل، بخش تازه باید با نسخه‌های مورد پشتیبانی host کار کند. manifest، نشانی remote و cache خروجی نیاز به مدیریت دارند. rollback باید بتواند نسخه مناسب را برگرداند بدون اینکه فایل لازم حذف شده باشد. تغییر ناسازگار باید مسیر مهاجرت داشته باشد. استقرار مستقل زمانی معنی دارد که مخاطب در ترکیب واقعی محصول همچنان کارش را انجام دهد.

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

امنیت و اختیار انتشار

remote اجرایی که در زمینه host بارگذاری می‌شود بخشی از کد قابل اعتماد آن زمینه است. مجوز دسترسی و منبع انتشار باید کنترل شوند. تقسیم مالکیت سازمانی به معنی جداسازی امنیتی کامل runtime نیست. سیاست script، integrity و نسخه باید با روش ادغام هماهنگ شود. در iframe، مرز دیگری وجود دارد و همان فرض‌ها را نباید بی‌تفاوت منتقل کرد. ابزار ادغام باید با مدل تهدید پروژه انتخاب شود.

مخزن، pipeline و دسترسی‌ها هم قرارداد می‌خواهند. اگر هر تیم اختیار تغییر فایل مشترک حیاتی را بی‌خبر دارد، انتشار مستقل می‌تواند به اختلال مشترک تبدیل شود. مسئول حادثه و مسیر تصمیم rollback را از پیش تعیین کنید. درباره مرز تغییر و تاریخچه، راهنمای Git مکمل است. روش شاخه‌ها به‌تنهایی معماری را مستقل نمی‌کند، ولی همکاری قابل پیگیری را کمک می‌کند.

انتخاب بر اساس هزینه واقعی

پیش از مهاجرت، یک حوزه با مرز روشن را انتخاب و قرارداد آن را مستند کنید. هزینه build، release، نسخه shared package و رفتار شکست را با مسئله اولیه مقایسه کنید. اگر coupling کم نشده و فقط تعداد ابزارها بیشتر شده، مرزها را دوباره بررسی کنید. monolith ماژولار می‌تواند برای بعضی تیم‌ها انتخاب مناسب‌تری باشد؛ تصمیم باید به نیاز و شواهد همان پروژه متکی باشد.

Micro-frontends وقتی ارزش دارد که مالکیت و تغییر مستقل را با تجربه قابل اعتماد هماهنگ کند. تنوع فناوری می‌تواند ممکن باشد، اما هدف لازم نیست کنار هم گذاشتن بیشترین frameworkها باشد. مرز محصول، قرارداد داده و مسیر انتشار را روشن نگه دارید و مسئولیت‌های مشترک را حذف‌شده فرض نکنید. معماری قابل نگهداری از همین توافق‌ها ساخته می‌شود و به نام روش یا اندازه سازمان وابسته نمی‌ماند.

واکنش به این مقاله

اشتراک‌گذاری این مقاله:
دیدگاه‌ها 0
۰ / ۲۰۰۰

هنوز دیدگاهی ثبت نشده

اولین نفری باشید که نظر می‌دهد!