نگهداری، توسعه، تست و پیادهسازی Monolithic frontendها دشوار است. راهحل این دشواری micro frontendها هستند.و یک نوع معماری است که میتواند اثربخشی و کارایی را در بین تیمها افزایش دهد. در سالهای اخیر، محبوبیت میکروسرویسها افزایش بسیاری یافته است. بسیاری از سازمانها از این نوع معماری برای جلوگیری از محدودیتهای بزرگ monolithic backendها استفاده میکنند. درحالیکه مطالب زیادی در این باره نوشته شده است، بسیاری از شرکتها همچنان در رابطهبا monolithic frontendها مقاومت میکنند. در این مقاله، ما روندی را توصیف میکنیم که frontend monolithها را به قطعات بسیار کوچکتر و قابلکنترلتر تقسیم میکند و اینکه این معماری چگونه میتواند اثربخشی و کارایی را در بین تیمها افزایش دهد. شکل 1 یک اپلیکیشن را نشان میدهد که در آن frontend از یک frontend monolith و backend آن از چندین میکروسرویس تشکیل شده است.
.اگر تمایل دارد با معماری میکروسرویس بیشتر آشنا شوید .به دوره رایگان آموزش میکروسرویس در سایت سر بزنید و این دوره رایگان رو دانلود کنید وببینید
شکل (1)
Micro Frontend چیست؟
تعریف micro frontends: ایده micro frontends این است که مفاهیم میکروسرویسها را به دنیای frontend گسترش دهد. ایده اصلی micro frontends این است که frontend خود را به مجموعهای از اپلیکیشنهای frontend که به طور مستقل و با loosely coupled (حداقل وابستگی) قابلاجرا هستند، تقسیم میکند (micro frontends نامیده میشوند). سپس این micro frontendها برای ایجاد یک اپلیکیشن frontend واحد، با هم ادغام شده و باندل میشوند (شکل 2 را ببینید). این مجموعه micro frontends در پاراگراف Integration Approaches Micro Front Ends موردبحث قرار میگیرد.
اولین سؤال چگونگی split کردن اپلیکیشنهای front-end است؟ شما میتوانید یک micro frontend در هر پیج نشان دهید و آن را با هایپر لینکها کانکت کنید. همچنین آیا امکان نمایش چندین micro frontend در یک پیج وجود دارد؟ (شکل 2 را ببینید).
شکل (2)
برای سرعت بخشیدن به توسعه یک اپلیکیشن، micro frontendها را بهعنوان بخشهای عمودی جداگانه یک برنامه وب در نظر بگیرید (همچنین verticals نامیده میشود). هر vertical مسئول یک دامنه تجاری واحد مورداستفاده مانند Profile، Catalog ، Order است. این presentation layer (لایه نمایشی) ، لایه سرویس (microservice) ، لایه ماندگاری و دیتابیس جداگانه خود را دارد. از نظر توسعه، هر vertical توسط یک تیم اجرا میشود.
چرا این کار روند توسعه را سرعت میبخشد؟ هر تیم vertical بر یک دامنه تجاری متمرکز است و بنابراین نیاز به هماهنگی کمتری با سایر تیمها دارد. ترجیحاً هیچ کدی بین verticalهای مختلف به اشتراک گذاشته نمیشود. این باعث افزایش سرعت پردازش توسعه میشود. برای سادگی، در این مقاله، ما فقط بر روی لایه نمایشی vertical تمرکز میکنیم.
اپلیکیشن نمونه
در ادامه یک اپلیکیشن را بهعنوانمثال توصیف میکنیم که از micro frontendها استفاده میکند. وبسایتی را تصور کنید که در آن کاربران میتوانند غذا را برای تحویل سفارش دهند. اول، شما یک صفحه فرود دارید که در آن کاربران میتوانند رستورانها را جستجو کرده و فیلتر کنند. این micro frontend برای این مورداستفاده میشود (شکل 4 را ببینید): micro-frontend-browse-restaurants.
سپس هر رستوران پیج مخصوص خود را دارد که آیتمهای منو در آن نمایش داده میشود و مشتری میتواند سفارش خود را انتخاب کند (شکل 3 را ببینید). برای این منظور از micro-frontend-order-food استفاده میشود. در نهایت، مشتریان یک پیج پروفایل دارند که میتوانند سابقه سفارش خود را مشاهده کرده، سفارش را پیگیری کرده و گزینههای پرداخت خود را سفارشی کنند micro-frontend-user-profile. برای این کار استفاده میشود.
این اپلیکیشن نمونه در سراسر ادامه این مقاله استفاده میشود.
شکل (3)
معماری
معماری این اپلیکیشن به شرح زیر است:
چندین micro frontends در هر پیج نشان داده میشود و یک اپلیکیشن کانتینر بهعنوان نقطه ورود اصلی استفاده میشود (شکل 4 را ببینید) و مسئول موارد زیر است:
- مسیریابی درخواستها و تجمیع پاسخهای backend
- مدیریت Cross-cutting concerns مانند احراز هویت و سندیت، مجوز، لاگین، کَش کردن و جهتیابی مسیرهای مختلف.
- micro frontendهای مختلف (توزیع شده) را با هم در پیج قرار میدهد و تعیین میکند که کدام micro frontend باید در کجا و در چه زمانی ارائه شود.
شکل (4)
Integration Approaches Micro Front Ends
منظور از integration approaches این است که چگونه میتوان micro frontends را در frontend باندل کرد؟ شکل 5 سه integration approaches را نشان میدهد.
شکل (5)
برای Build time integration ، ما هر یک از micro frontend را بهعنوان یک پکیج منتشر میکنیم. در Build time، این micro frontends جداگانه با استفاده از package.json اپلیکیشن کانتینر، بستهبندی میشوند .Monorepo برای ادغام Build time استفاده میشود. با استفاده از Monorepo میتوانید تمام کد خود را در چندین کتابخانه در یک مخزن مدیریت کنید. کتابخانهها میتوانند شامل ویژگیها، اجزاء، ابزارهای کاربردی یا کیت UI باشند. ایده Monorepo این است که بهراحتی میتوانید از ویژگیهای ایجاد شده در monorepo استفاده مجدد کنید. عیب بزرگ Monorepo این است که باید مجدداً کامپایل کرده و هر micro frontend را در Monorepo منتشر کنیم که باعث ایجاد تغییر در یک micro frontend جداگانه شود. برای ایجاد و نگهداری Monorepo میتوانید از Lerna ، Nrwl یا Angular Workplace استفاده کنید.
Server-Side Integration
SSI در حال ارائه HTML روی سرور از چندین فرمت یا قطعه است. این قطعات نمایانگر micro frontendها هستند. در مثال زیر، index.html نشاندادهشده است که از server-side شامل قطعاتی از فایلهای HTML استفاده میکند (شکل 6 را ببینید).
شکل (6)
index.html
ما این فایل را با وب سرور Nginx ارائه میدهیم (شکل 7 را ببینید) ، متغیر $ PAGE را مطابق با URL (Uniform Resource Locator)درخواست شده پیکربندی میکنیم؛ بنابراین اگر کاربر URL /browse را انتخاب کند، متغیر $ PAGE با قطعه HTML browse پر میشود.
شکل (7)
Nginx
موردی که اینجا نشان داده نشده است نحوه پایان یافتن بخشهای مختلف قطعه HTML در سرور وب است. فرض بر این است که هرکدام pipeline ساخت خود را دارند و به ما اجازه میدهند بدون تأثیر بر پیج دیگر، در یک قطعه تغییراتی ایجاد کنیم.
Runtime Integration
Runtime Integration باندل کردن و پیکربندی micro frontends در frontend در Runtime است (شکل 5 را ببینید). در این وضعیت، package.json برای باندل کردن micro frontendها استفاده نمیشود. در مثال زیر، Web Components بهعنوان تکنیکی برای ایجاد micro frontends استفاده میشود. این Web Components همچنین میتوانند برای integration approaches قبلی استفاده شوند.
Web Components چیست؟
به طور خلاصه، Web Components اجزای ایزوله شدهای هستند که میتوانید (مجدداً) در پیجهای HTML و اپلیکیشنهای وب استفاده کنید. Web Components همچنین بهعنوان عناصر خاص (Custom Element)شناخته میشوند. بهعنوان یک توسعهدهنده، میتوانید Custom Element خود را بنویسید که اساساً عنصر HTML شما با CSS ، HTML و Javascript است. این Custom Element بر اساس استانداردهای وب بوده و میتواند در رایجترین مرورگرها استفاده شود. Web Componentها به دلیل عدم وابستگی آنها به فریمورک یا کتابخانه، یکی از تکنولوژیهای بسیار محبوب در آینده خواهند بود (منسوخ نخواهند شد). یعنی به هیچ فریمورکی نیاز نداشته و با تمام فریمورکها سازگار هستند و بنابراین بهعنوان یک تکنیک برای ساختن یک micro frontend بسیار مناسب است.
چگونگی ساخت یک Web Component
در این مثال، ما قصد داریم Web Component خود را از پیج order food (شکل 3 را ببینید) از اپلیکیشن مثالی خود ایجاد کنیم. نام این وب کامپوننت micro-frontend-order-food است و در این مثال (شکل 8 را ببینید) دارای پارامترهای زیر است: data-name ، data-img و data-menu.
شکل (8)
پیاده سازی این Web Component به این شکل است (شکل 9 را ببینید). برای حفظ سادگی مثال، آیتمهای منو حذف شده است.
برای این Web Component ، ابتدا یک کلاس تعریف میکنیم که HTMLElement را گسترش میدهد. با HTMLElement میتوانید یک عنصر Custom HTML ایجاد کنید. در سازنده، اول super () فراخوانی میشود، بدین معنی که میتوان از تمام منطق HTMLElement برای ساخت یک Web Component استفاده کرد. بعد، یک( (Document Object Model shadow DOM را به Web Component ضمیمه میکنیم .shadow DOM یک DOM ایزوله شده یاView است که چیزی را برای این Web Component نمایش دهد.
ما تصویر موردنظر را با document.createElement ('img') بهعنوانمثال ذکر میکنیم و مشخصههای 'alt' و 'src' را با استفاده از پارامترهای پاس شده تنظیم میکنیم: data-name و data-img. سپس تصویر به shadow DOM ما با shadow.appendChild (img) اضافه میشود.
شکل (9)
و در نهایت، یک Custom Element / Web Component جدید با موارد زیر تعریف شده است:
JavaScript
customElements.define(‘ micro-frontend-order-food’, MicroFrontendOrderFood)
این Web Component را micro-frontend-order-food مینامند. ما میتوانیم از این موارد در صفحات HTML خود برای نمایش تصویر با متن استفاده کنیم.
مثال Runtime Integration با Web Components
یک index.html در شکل 10 نشاندادهشده است که اپلیکیشن نمونه ما (ordering food) را شبیهسازی میکند. این index.html در اینجا نشاندهنده اپلیکیشن کانتینری است که از مسیریابی و رندرینگ micro frontendها میان سایر چیزها محافظت میکند. در بالا، micro frontendهای ما دارای <script> tags هستند. micro-frontend-order-food که موردبحث قرار گرفت، دربسته نرمافزاری جاوا اسکریپت تعریف شده است: https: // order.example.com/bundle.js
<div id="micro-frontend-root"> یک placeholder است که در آن micro frontendها انتخاب شده و ارائه میشوند. webComponentsByRoute ثابت دارای یک جدول جستجو برای تعیین web component / micro frontend است که میخواهید هنگام انتخاب یک مسیر ارائه دهید. webComponentType ثابت شامل micro frontend انتخاب شده واقعی بر اساس مسیر انتخاب شده از طریق window.location.pathname میباشد.
شکل (10)
با استفاده از) document.createElement web ComponentType) ما micro frontend انتخاب شده را بهعنوانمثال در نظر میگیریم. درنهایت به placeholder: <div id="micro-frontend-root"> لینک داده میشود. این کار با root.appendChild (webComponent) انجام میشود. مثال بالا صریحاً یک مثال اولیه و بدوی است، اما رویکرد ادغام Runtime را نشان میدهد.
از کدام رویکرد Integration استفاده کنیم؟
باتوجهبه نمودار زیر (در شکل 11) متوجه خواهید شد که در کدام موقعیت از کدام رویکرد Integration میتوانید استفاده کنید. برای اپلیکیشنهای کوچک یا غیر پیچیده (جایی که 1 یا 2 تیم روی آن کار میکنند) میتوانید رویکردهای integration را نادیده بگیرید و فقط frontend monolith را فرض کنید.
شکل (11)
کتابخانه کامپوننت UI شامل مجموعهای از بلوکهای ساخت UI ، مانند عناصر ورودی، لیستها، تب بارها، و شبکهها و غیره است.
شما میتوانید انتخاب کنید که هر micro frontend دارای کتابخانه UI Component مختص به خود باشد (شکل 12 را ببینید). از معایب آن میتوان به کد تکراری (duplicate)و امکان سازگاری و ثبات کمتر در طراحی و عملکرد اجزای UI اشاره کرد. همچنین برای ثبات بیشتر، میتوانیم کتابخانه کامپوننت UI ژنریک را به کار ببریم. از معایبش این است که micro frontendها از طریق این کتابخانه به هم لینک داده میشوند. اگر یک کامپوننت UI ژنریک را انتخاب میکنید، مطمئن شوید که فقط حاوی منطق UI است و هیچ منطق تجاری یا دامنهای ندارد. قراردادن منطق دامنه (domain logic)در یک کتابخانه مشترک، وابستگی بالایی رابین micro frontend ایجاد میکند.
شکل (12)
ارتباط بین Micro Frontends
یکی از سؤالات متداول در مورد micro frontendها نحوه ایجاد ارتباط آنها با یکدیگر است. عموماً توصیه میشود ارتباطات micro frontendها تا حد کم و ممکن برقرار شود چون این یک لینک ناخواسته را معرفی میکند که ابتدا سعی میکنیم از آن اجتناب کنیم. بااینوجود، اغلب مقدار معینی ارتباط بین micro frontendها موردنیاز است. Custom events(رویدادهای سفارشی) باعث میشود تا micro frontendها با هم ارتباط غیرمستقیم برقرار کنند. Eventها را میتوان با Event constructor(سازنده رویداد) به شرح زیر ایجاد کرد: New Event (build) (شکل 13 را ببینید).
بهعنوانمثال، dispatchEvent میتواند در micro frontend X برای ارسال رویدادی به نام "build" آغاز شود. سپس Micro frontend Y شنونده این رویداد میشود (با استفاده از متد addEventListener) و پردازشهای بیشتری را انجام میدهد.
شکل (13)
نتیجهگیری Micro Frontends
Micro frontendها همه در مورد تجزیه یک برنامه وب بزرگ به Verticals هستند. انتخابهای تکنولوژی ما، پایگاههای کد، تیمها و فرایندهای انتشار ما (CI/CD) در حالت ایدئال میتوانند بدون هماهنگی بیش از حد بین سایر تیمها، مستقل از یکدیگر کارکرده و تکامل یابند. این معماری جنبه منفی نیز دارد. در اینجا به چند مورد اشاره میکنیم:
اگر بخواهید در کل برنامه وب تغییری ایجاد کنید، باید تغییراتی را در micro frontendهایی (و میکروسرویسها) که توسط تیمهای مختلف دیگر اجرا شده است، ایجاد کنید.
برای تست integration کل برنامه وب، باید اپلیکیشنها و سرورهای مختلفی را راهاندازی کنید. مشکل در آزمایش وابستگیها و ارتباط بین micro frontendها (توزیع شده) است.
micro frontendهای مستقل میتوانند حاوی کد تکراری باشند که باعث افزایش تعداد بایتهایی میشود که باید برای کاربران نهایی خود در شبکه ارسال کنیم. کد تکراری همچنین به معنی تعمیر و نگهداری بیشتر، احتمال خطای بیشتر و سازگاری کمتر در طراحی و عملکرد اجزای UI است.
علاوه بر این، موارد کاربردی زیادی وجود دارد که در آنها micro frontend مزایایی را ارائه میدهد. سازمانهای بزرگی مانند Spotify یا IKEA موفق شدهاند بهتدریج از micro frontendها در کدبیس های قدیمی و جدید استفاده کنند. این شرکتها با استفاده از micro frontendها میتوانند سریعتر به تغییرات در بازار پاسخ دهند و تجربیات مشتری را ارائه دهند و با این کار برند خود توسعه دهند.
برای افزودن دیدگاه خود، نیاز است ابتدا وارد حساب کاربریتان شوید