چگونه یک پیاده سازی واقعی به سبک Micro Frontends داشته باشیم - قسمت اول

امروزه توسعه برنامه های کاربردی بر پایه وب دنیای جدیدی رو تجربه می کند. علاوه بر ظهور فریم ورک ها و کتابخانه های متفاوت و قدرتمند در این حوزه، به نظر من نکته ای که حرکت به سمت این دنیای جدید را بیشتر نشان می‌دهد، ظهور و بروز مباحث معماری در حوزه فرانت اند است. مباحثی که هنوز هم شاید از دید بعضی ها فقط مربوط به حوزه بک اند هستند.یکی از مهمترین مباحثی که این روزه در این حوزه مطرح می‌شود موضوع Micro frontends هست. تعریف های متفاوتی برای Micro frontends وجود دارد؛ اما شاید یکی از بهترین تعاریف، این تعریف باشد :"An architectural style where independently deliverable frontend applications are composed into a greater whole"(https://martinfowler.com/articles/micro-frontends.html)شاید این چند خط هم کمک کند که درک بهتری پیدا کنیم:Think about a website or web app as a composition of features which are owned by independent teams. (https://micro-frontends.org/)هدف من در این نوشته معرفی Micro frontends نیست. اما خوب اگر قبلا در این مورد مطالعه ای نداشته اید توصیه می‌کنم حتما سری به مقالات و کتابهایی که معرفی می‌کنم بزنید و بعد ادامه این مطلب را مطالعه کنید.مقالات و کتابهای مفید در مورد Micro frontendshttps://martinfowler.com/articles/micro-frontends.htmlhttps://www.manning.com/books/micro-frontends-in-actionhttps://www.oreilly.com/library/view/building-micro-frontends/9781492082989/همانطور که در ابتدای نوشته مطرح شد هدف من در این نوشته معرفی Micro frontends نیست و اگر شما مطالب معرفی شده و بقیه مطالب مشابه را مطالعه کنید می‌توانید دید خوبی نسبت به مفاهیم پیدا کنید. اما مشکل اصلی معمولا اینجاست که این مفاهیم را چطور می‌شود پیاده سازی کرد. شاید هم بشود مثالهایی از پیاده سازی برای موارد خیلی ساده پیدا کرد اما وقعا برای یک Enterprise application چطور می‌شود این مفاهیم و این معماری را پیاده سازی کرد. در طی این دو سالی که در شرکت همکاران سیستم به همراه یک تیم بزرگ و حرفه ای مشغول پیاده سازی یک سیستم واقعا بزرگ با سبک معماری Micro Frontends بوده ایم متوجه شدم که هر چند مطالعه مقالات و کتابها می تواند مسیر را برای ما روشن کند و به حرکت ما جهت دهد، اما حرکت در این مسیر نیازمند داشتن دانش و تجربه بسیار بیشتری است تا در برخورد با چالشها و انتخاب جهت گیری ها بتوان بهترین تصمیم ها را گرفت. البته آنچه که در این نوشته به آن می پردازم پیاده سازی یک مثال کوچک است و با رویکردی حتی متفاوت از آنچه که در این مسیر دو ساله در همکاران سیستم رفته ایم.هر چند این مثال هم حتما قابل گسترش هست و می‌تواند به عنوان مبنا برای Enterprise Application ها هم قرار بگیرد. البته من در نوشته های بعدی این مسیر را ادامه خواهم داد و امیدوارم شما هم در این مسیر با من همراه باشید. برای آشنایی بیشتر با آنچه که در همکاران سیستم انجام داده ایم میتوانید این ارائه را ببینید.رویداد آنلاین رونمایی از معماری رابط کاربری جدید همکاران سیستماین مطلب در دو قسمت نوشته می شود. در قسمت اول درباره اینکه قرار است چه چیزی و چطور پیاده سازی شود صحبت می‌کنم و در قسمت دوم هم درباره جزییات پیاده سازی صحبت خواهم کرد . اما قبل از اینکه شروع کنم باز هم روی یک مساله تاکید می‌کنم. مطمئنا برای پیاده سازی یک محصول بر پایه Micro Frontends نیازمند داشتن دانش و پرداختن به مسائل بیشتری از آنچه که در این نوشته مطرح شده است، هستید. مثلا اینکه چطور یک سیستم بزرگ را به app های کوچکتر بشکنیم، این app ها چطور با یکدیگر ارتباط داشته باشند، چطور در نهایت با هم ترکیب بشوند، استراتژی های مربوط به versioning و deployment و موارد دیگر. دقت کنید که مثلا موضوعاتی مثل شکستن app ها در این مثال به گونه ای انجام شده است که درک بهتری از روش پیاده سازی به ما بدهد و احتمالا در یک پروژه واقعی شاید شکست app ها به گونه ای متفاوت انجام شود.مقدمات قدری طولانی شد. پس بهتر است برویم سراغ اصل مطلب. قرار است در این مثال یک سایت خرید اینترنتی ساده را پیاده سازی کنیم. این سایت شامل صفحه ای است که لیست کالا ها را نشان میدهد و کاربر امکان اضافه کردن کالاها از این لیست به سبد خرید را دارد. سبد خرید چیزی شبیه همه سبد های خریدهایی است که در سایت‌های مشابه دیده اید به همراه صفحه نهایی کردن خرید که شامل محاسبات ساده و انتخاب روش پرداخت است. در کنار اینها یک قسمت ساده هم برای نمایش اطلاعات کاربر جاری و احتمالا ویرایش این اطلاعات داریم. در ادامه صفحات پیاده سازی شده این مثال را با هم می‌بینیمصفحه کالا و سبد خریدصفحه نهایی کردین خریدنمایش مشخصات و پروفایل کاربرهمانطور که می بینید این مثال شامل سه صفحه ساده است. حالا اگر بخواهیم این مثال را با سبک معماری Micro Frontends پیاده سازی کنیم به نظر شما سیستم ما به چه app هایی شکسته خواهد شد؟قبل از اینکه در مورد app ها صحبت کنیم من این مثال را به چهار حوزه اصلی تقسیم می‌کنمShellدر واقع container اصلی است و بیشتر وظیفه مشخص کردن layout و مکانهای قرارگیری app های دیگر را بر عهده دارد و احتمالا شامل بیزنس خاصی نخواهد بودUserمدیریت هر آنچه که مربوط به کاربر است در این حوزه خواهد بود. مسائلی مانند ورود به سیستم، تغییر پروفایل، آدرس ها و موارد مشابهProductنمایش اطلاعات کالاها به شکل ها و ترتیب های مختلف در این حوزه انجام خواهد پذیرفتShopping Cartمسائل مربوط به سبد خرید مثلا نمایش موارد اضافه شده، کم و زیاد کردن آنها، انجام محاسبات و نهایی کردن سفارش در این حوزه انجام می شود .در این قسمت می توانیم گریزی بزنیم به مفاهیم Micro Frontends. آیا ما برای هر کدام از این حوزه ها یک تیم مستقل داریم؟ الزاما نه. ولی اگر قرار است ما تیم های مختلفی داشته باشم می توانیم تیم ها را بر اساس این حوزه ها تقسیم بندی کنیم و از یکی از بزرگترین مزایای Micro Frontends بهره مند شویمAs a higher-order benefit of decoupling both our codebases and our release cycles, we get a long way towards having fully independent teams, who can own a section of a product from ideation through to production and beyond(https://martinfowler.com/articles/micro-frontends.html)پس ما دارای چهار app خواهیم بود؟ می‌توانیم بگوییم حداقل چهار app. هر تیم ممکن است بیشتر ازیک app را توسعه دهد. ولی واقعا ما در این مثال چند app خواهیم داشت؟ پاسخ به این سوال وابستگی زیادی به تعریف ما از app دارد. طبق تعریفی که من از app دارمهر قطعه ای که به صورت مستقل بتواند develop و deploy شود یک app است.پس با این تعریف، تعداد app های ما بیشتر خواهد بود. برای مثال در حوزه Shopping Cart یک app داریم که شامل دکمه سبد خرید است در header صفحه، یک app که کار انجام محاسبات مربوط به tax را انجام میدهد و و حتی سه app دیگر . یعنی app ها ممکن است در حد یک قطعه کوچک UI( چیزی شبیه Plugin) و یا حتی یک سرویس باشند. ممکن است در برخی نوشته ها اینها را app مستقل ندانند و به عنوان قسمتهایی از یک app بزرگتر به حساب آورند. با توجه به این صحبتها، app های موجود در این مثال را می توانید در شکل زیر ببینید:همانطور که در تصویر مشخص است در این مثال ما ده app داریم. برای آشنایی در مورد هر کدام توضیح مختصری می دهم.Shell:در مورد Shell قبلا توضیح دادم. این app وظیفه مشخص کردن layout برنامه را برعهده دارد. اینکه منو در کجا قرار بگیرد. دکمه نمایش سبد خرید در کجا قرار بگیرید، بقیه صفحات قرار است در کجا لود شوند و … .Shopping Cart Button:دکمه ای است که در اکثر سایتهای مشابه می بینید. در بالای صفحه قرار می گیرد و وضعیت سبد خرید شما را نمایش می دهد. اگر روی آن کلیک کنید جزیات بیشتری از سبد خرید را نمایش می دهد و پس از کلیک رو دکمه نهایی کردن خرید شما را به صفحه نهایی کردن خرید راهنمایی می کند.Shopping Cart: این app در واقع صفحه نهایی کردن سفارش است. در این صفحه کاربر سبد خرید را مشاهده میکند . میتواند برخی از اقلام را حذف کند. محاسبات نهایی و حمع پرداختی کاربر نمایش داده می شود و کاربر می تواند نحوه پرداخت و مشخصات آن را مشخص کند.Shopping Cart Service:یک سرویس است که هیچ نمود ظاهری ندارد. وظیفه مدیریت اطلاعات سبد خرید را به عهده دارد. در جرییات پیاده سازی بیشتر در مورد این سرویس خواهم گفت.Payment Type 1:صفحه ای است که اگر کاربر نحوه پرداخت نوع 1 را انتخاب کند لود می شود تا اطلاعات مورد نظر را از کاربر بگیرید.Payment Type 2:صفحه ای است که اگر کاربر نحوه پرداخت نوع 2 را انتخاب کند لود می شود تا اطلاعات مورد نظر را از کاربر بگیریدProducts:صفحه ای است که لیست محصولات را به کاربر نمایش می دهد و کاربر می تواند محصولات مورد نظر را به سبد خرید اضافه کند.User Profile:صفحه نمایش/ویرایش اطلاعات کاربر .Current User Button:دکمه ای که در بالای صفحه قرار میگیرد و در صورتی که کاربر وارد صفحه شده باشد اطلاعات کاربر را نمایش می دهد و احتمالا با امکاناتی مانند خروج از سیستم و موارد مشابه.شاید مجدد این سوال مطرح شود که چه لزومی دارد که یک سیستم به app های به این کوچکی تقسیم شوند. در پاسخ باید به چند نکته اشاره کنم:همانطور که گفتم این یک مثال است و شاید شما اینگونه فرایند شکستن سیستم را انجام ندهید.موارد مطرح شده در این مثال خیلی ساده هستند ولی اگر با سیستم های واقعی کار کرده باشید حتما می‌دانید که مثلا صفحه نمایش کالا حاوی چه جزییات و پیچیدگیهای مهمی می‌تواند باشد که شاید یک تیم را برای مدتها به خود مشغول کند.شکستن سیستم به app های کوچک این امکان را به شما می‌دهد که هر قطعه از سیستم جدا توسعه پیدا کند، جدا تست شود و جدا deploy شود. این یک امتیاز خیلی مهم است. تیمهای متمرکز بر موضوعات مشخص. مثلا ممکن است سرویسهای محاسبه به صورت مستقل این فرایند را طی کنند و راحت بتوانند جایگزین هم شوند. البته خیلی مهم است که بدانید در مقابل چیزهایی که به دست می‌آورید چه چیزهایی را از دست می‌دهید.شاید دلیل جدا شدن بعضی قسمتها ماهیت مختلف آن قسمت باشد. به عنوان مثال Current User Profile یک app جدا از User profile شده است. زیرا در همان ابتدا لازم است در header بالا و در دل Shell لود شود ولی User Profile فقط وقتی کاربر در خواست صفحه مورد نظر را داد لود و نمایش داده می‌شود. پس بهتر است تا Current User App به صورت یک bundle مستقل و بسیار سبک باشد.در قسمت دوم این نوشته به بیان جزییات پیاده سازی خواهم پرداخت.چگونه یک پیاده سازی واقعی به سبک Micro Frontends داشته باشیم- قسمت دوم