Anophel-آنوفل میکرو-فرانت اند در Next.js بررسی همراه با مثال

میکرو-فرانت اند در Next.js بررسی همراه با مثال

انتشار:
1

مدیریت پایگاه کد یک پروژه بزرگ در حین کار روی آن برای تیم ها آسان نیست. Micro-frontend (میکرو فرانت اند) ها برای مدت طولانی کاربردی بوده اند، اما به دلیل ویژگی های متمایز و راحتی که دارند، در بین کاربران محبوب شده اند.تیم های مختلف می توانند بر روی وظایف مجزای یک پروژه واحد بدون فکر کردن به وظایف دیگر با فرانت اند های خرد عمل کنند. تفاوتی در تعداد ماژول هایی که در هنگام استفاده از micro-frontends به یک سیستم موجود اضافه می شود وجود ندارد.


اما سوال بزرگ این است که میکرو فرانت اند چیست؟ بیایید یاد بگیریم که چیست و چگونه معماری Micro-Frontend را با React و Next JS پیاده سازی کنیم!

میکرو فرانت اند چیست؟

Micro Front Ends مانند میکروسرویس ها برای قسمت فرانت اند هستند. در مورد آن به عنوان یک کد یا کامپوننت محصور شده و مستقل در نظر بگیرید که می تواند در هر جایی مصرف شود. طبق وبسایت micro-frontends:

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

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

ساختار یک اپلیکیشن e-commerce - آنوفل | Anophel

Micro frontend با به کارگیری اصول میکروسرویس ها در frontend راه حلی برای این مشکل ارائه می دهد. با تقسیم آن به بخش‌های کوچک و مستقل، هر تیم می‌تواند قطعات خود را به طور مستقل توسعه داده و مستقر کند، بدون اینکه نگران تأثیرگذاری بر سایر اجزاء باشد. راه‌های مختلفی برای ساخت فرانت‌اندهای میکرو وجود دارد که هر کدام مزایا و معایب خود را دارند. در این مقاله، ما بر روی یک روش خاص برای ساخت اپلیکیشن micro frontend تمرکز خواهیم کرد که شامل Module Federation و Next.js می شود.

فدراسیون ماژول چیست؟

از نظر فنی، Module Federation یک ویژگی Webpack v5 است که به build های جداگانه (Webpack) از یک برنامه واحد اجازه می‌دهد. با این حال، خیلی بیشتر از این…


به تعبیر زک جکسون ، یکی از سازندگان ماژول فدراسیون:


“این یک معماری کاربردی توزیع شده است. بسته‌های مستقل مستقر شده‌اند که در زمان اجرا به‌عنوان یکپارچه کار می‌کنند.»


بنابراین، در چند نکته:

این یک نوع معماری جاوا اسکریپت است.

این اجازه می دهد تا یک برنامه جاوا اسکریپت به صورت پویا کد را از برنامه دیگری بارگیری کند

این امکان به اشتراک گذاری وابستگی ها را فراهم می کند، اگر برنامه ای که یک ماژول فدرال را مصرف می کند وابستگی مورد نیاز کد فدرال را نداشته باشد، Webpack وابستگی گمشده را از آن مبدأ ساخت فدرال دانلود می کند.
هماهنگ شده در زمان اجرا نه زمان ساخت، بدون نیاز به سرور، گلوبال

Module Federation یک رویکرد مبتنی بر ابزار برای اجرای معماری micro front-end است.


مهم است که Federation Module را با Webpack DllPlugin که ابزاری است که بیشتر بر روی بهبود عملکرد زمان ساخت متمرکز است، اشتباه نگیرید. می‌توان از آن برای ساخت برنامه‌های وابسته به DLL (کتابخانه پیوند پویا) استفاده کرد، اما این می‌تواند باعث تأخیر در استقرار شود، زیرساخت اضافی برای وابستگی به زمان کامپایل وجود دارد، زمانی که قطعات تغییر می‌کنند نیاز به بازسازی دارد (که باعث تأخیر در استقرار می‌شود) و به شدت به کد خارجی و بدون خطای ایمن وابسته است. به طور خلاصه، DLL ها با برنامه های متعدد مقیاس نمی شوند و برای اشتراک گذاری به کارهای دستی زیادی نیاز دارند.

webpack در مقابل Vite.js کدام یک بهتر است؟


از سوی دیگر، Module Federation بسیار انعطاف پذیر است در حالی که به دلیل نیاز به تنها کد و برنامه مشترک برای ساخت، تنها تاخیر در استقرار کمتری را امکان پذیر می کند. این شبیه به فدراسیون Apollo GraphQL است اما برای ماژول های جاوا اسکریپت، مرورگر و Node.js اعمال می شود.


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


Host: یک ساخت Webpack که ابتدا در طول بارگذاری صفحه مقداردهی اولیه می شود
Remote: یک ساخت وب پک دیگر که بخشی از آن توسط یک "host" مصرف می شود.
میزبان دوطرفه: قابل مصرف و مصرف است
Hosts Omnidirectional: میزبانی که به طور همزمان مانند یک کنترل از راه دور و میزبان عمل می کند

آشنایی با Module Federation - آنوفل | Anophel

NextJS چیست؟

اگر با اکوسیستم frontend/React آشنایی ندارید یا در دنیای فرانت اند تازه وارد هستید، NextJS یک چارچوب React برای ساخت برنامه React استاتیک هیبریدی و رندر سمت سرور است. اساساً، بسیاری از دردسرهای پیکربندی، سرهم‌بندی، و بهسازی آنچه را که برای رساندن یک برنامه (یا وب‌سایت) React به تولید نیاز است، از بین می‌برد. برای آشنایی با تفاوت های بین SSR و CSR و SSG این مقاله را از دست ندهید.


نکست دارای ویژگی های بسیار متنوعی است که باعث می شود هر توسعه دهنده وب با کم ترین دردسر کد نویسی کند.


برای نام بردن چند ویژگی کلیدی:

پیکربندی صفر
پشتیبانی TypeScript
سیستم روت مبتنی بر فایل
توابع بدون سرور داخلی (مسیرهای AKA API)
تقسیم و بسته بندی کد


به خاطر این پست، مهم است که به یاد داشته باشید که فریمورک ها دارای محدودیت هایی هستند و در این آموزش، ما با برخی از محدودیت های NextJS مبارزه می کنیم. تیم سازنده NextJS در مدت زمان کوتاهی پیشرفت های باورنکردنی داشته است. با این حال، برای اینکه بتوانیم از Module Federation استفاده کنیم، باید روی برخی از جنبه های کلیدی کار کنیم.

Next.js همچنین یک ویژگی قدرتمند به نام getServerSideProps را ارائه می دهد. این تابع به توسعه دهندگان اجازه می دهد تا داده ها را از یک API یا پایگاه داده خارجی در حین رندر سمت سرور واکشی کنند. داده ها را می توان بر روی سرور واکشی و پردازش کرد و در نتیجه زمان بارگذاری اولیه سریعتر و سئوی بهتری را به همراه داشت

ساختار یک پروژه Next.js - آنوفل | Anophel

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


برای غلبه بر این مشکل، می‌توان از Module Federation برای تقسیم برنامه Next.js به بخش‌های کوچکتر و مستقل‌تر استفاده کرد. خوشبختانه، تیم فدراسیون ماژول اعلام کرده است که تمام کارهای آنها در مورد Next.js به صورت متن باز در دسترس خواهد بود و توسعه دهندگان را قادر می سازد تا از این رویکرد در پروژه های خود استفاده کنند.

Next.js با فدراسیون ماژول

با استفاده از Module Federation با Next.js، برنامه را می توان به یک برنامه میزبان و یک یا چند برنامه از راه دور تقسیم کرد. برنامه Host مسئول رندر کردن پوسته برنامه است و می تواند کد را از برنامه های Remote مصرف کند. این برنامه های Remote به طور جداگانه ساخته و مستقر می شوند و امکان توسعه و تست مستقل را فراهم می کنند.

Next.js با Module Federation - آنوفل | Anophel

به عنوان مثال، فرض کنید یک صفحه اصلی در برنامه Next.js خود داریم که از اجزای مختلفی مانند Hero، Promo، Search و FeaturedProducts تشکیل شده است. به جای وارد کردن این کامپوننت ها به صورت محلی، Module Federation ما را قادر می سازد آنها را از برنامه های Remote وارد کنیم.


هر کامپوننت راه دور می تواند getServerSideProps خود را داشته باشد، به این معنی که کامپونت های راه دور می توانند هم مسئول واکشی داده ها و هم ارائه داده های خود باشند. جزئیات پیاده‌سازی پنهان هستند که تیم‌های توسعه را قادر می‌سازد تا به طور مستقل بر روی بخش‌های کوچک مربوطه خود کار کنند، که منجر به همکاری کارآمدتر و چرخه‌های توسعه سریع‌تر می‌شود.


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


در یک معماری micro frontend معمولی با استفاده از Module Federation، هر صفحه ممکن است چندین ماژول را از برنامه های راه دور وارد کند. با این حال، بسیار رایج است که یک صفحه فقط یک ماژول اصلی را وارد کند که نمایانگر صفحه کامل یا بخش قابل توجهی از آن از یک برنامه راه دور است.

این رویکرد مزایایی دارد:

یکپارچه سازی ساده: وارد کردن یک ماژول واحد در هر صفحه فرآیند یکپارچه سازی را ساده می کند، زیرا وابستگی های کمتری برای مدیریت و هماهنگی وجود دارد.


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


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


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


به‌روزرسانی‌های آسان‌تر: با یک ماژول در هر صفحه، به‌روزرسانی‌ها یا تغییرات را می‌توان به‌صورت مجزا و بدون تأثیر بر سایر صفحات انجام داد و فرآیند استقرار را ساده‌تر کرد.


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

ایجاد یک میکرو-فرانت اند با Next.js

به شدت توصیه می‌شوداین ریپو را مطالعه کنید، که دارای نمونه‌های کاربردی مختلف فدراسیون ماژول است: github.com/module-federation/module-federation-examples.


با فرض وجود دو پروژه خالی Next.js که توسط create-next-app با «module-federation/nextjs-mf@» نصب شده ایجاد شده است، یکی Host و دیگری Remote است. هاست روی پورت 3000 و Remote روی پورت 3001 اجرا می شود.


فقط سه مرحله برای کارکرد Module Federation با Next.js وجود دارد:


1. در برنامه Remote NextFederationPlugin را به next.config.js اضافه کنید و ماژول‌ها (کامپوننت‌ها یا صفحات) را تعریف کنید که باید به اشتراک گذاشته شوند.

 // remote/next.config.js
 const { NextFederationPlugin } = require('@module-federation/nextjs-mf');

 const nextConfig = {
   reactStrictMode: true,
   webpack(config, { isServer }) {
     config.plugins.push(
       new NextFederationPlugin({
         name: 'remote',
         filename: 'static/chunks/remoteEntry.js',
         exposes: {
           // specify exposed pages and components
           './SomePage': './pages/somePage.js',
           './SomeComponent': './components/someComponent.js'  
         },
         shared: {
            // specify shared dependencies 
            // read more in Shared Dependencies section
         },
       })
     );

     return config;
   },
 }

2.در برنامه Host NextFederationPlugin را به next.config.js اضافه کنید و ریموت هایی را مشخص کنید که باید مصرف شوند.

 // host/next.config.js
 const { NextFederationPlugin } = require('@module-federation/nextjs-mf');

 const remotes = (isServer) => {
   const location = isServer ? 'ssr' : 'chunks';
   return {
     // specify remotes
     remote: `remote@http://localhost:3001/_next/static/${location}/remoteEntry.js`,
   };
 }

 const nextConfig = {
   reactStrictMode: true,
   webpack(config, { isServer }) {
     config.plugins.push(
       new NextFederationPlugin({
         name: 'host',
         filename: 'static/chunks/remoteEntry.js',
         remotes: remotes(isServer),
         exposes: {
           // Host app also can expose modules
         }
       })
     );

     return config;
   },
 }

3. اکنون ماژول های راه دور می توانند توسط برنامه Host با استفاده از next/dynamic مصرف شوند.

 // host/pages/someLocalPage.js
 import dynamic from 'next/dynamic';

 const RemotePage = dynamic(() => import('remote/SomePage'));

 export function LocalPage(props) {
   return <RemotePage {...props} />
 }

 export const getServerSideProps = async (ctx) => {
   const remotePage = await import('remote/SomePage');

   if (remotePage.getServerSideProps) {
     return remotePage.getServerSideProps(ctx)
   }

   return {
     props: {},
   }
 }

 export default LocalPage;

وابستگی های مشترک

در فرآیند توسعه برنامه های کاربردی وب، اغلب به استفاده از وابستگی های شخص ثالث نیاز است. این هم برای برنامه‌های سنتی و هم برای برنامه‌های micro frontend صادق است، جایی که برنامه‌های میزبان و راه دور ممکن است وابستگی‌هایی مانند CSS-in-JS، مدیریت استیت یا کتابخانه‌های واکشی داده‌ها را به اشتراک بگذارند.

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

از طریق گزینه اشتراک‌گذاری - ریموت‌ها به وابستگی‌های میزبان بستگی دارند، اگر میزبان وابستگی نداشته باشد، کنترل از راه دور خودش را دانلود می‌کند. بدون تکرار کد، اما افزونگی داخلی.

در اینجا یک مثال با یک کتابخانه مشترک Chakra UI آورده شده است.

const { NextFederationPlugin } = require('@module-federation/nextjs-mf');

const nextConfig = {
  webpack(config, { isServer }) {
    config.plugins.push(
      new NextFederationPlugin({
        name: 'shop',
        filename: 'static/chunks/remoteEntry.js',
        remotes: {},
        exposes: {
          './Featured': './pages/featured.js',
          './Search': './pages/search.js',
        },
        shared: {
          '@emotion/': {
            eager: true,
            requiredVersion: false,
            singleton: true,
          },
          '@chakra-ui/': {
            eager: true,
            requiredVersion: false,
            singleton: true,
          },
        },
      })
    );

    return config;
  },
}

module.exports = nextConfig

گزینه singleton برای اطمینان از اینکه تنها یک نمونه از یک ماژول مشترک در همه برنامه های فدرال استفاده می شود استفاده می شود. هنگامی که ویژگی singleton را روی true تنظیم می کنید، به Webpack می گویید که باید فقط یک نمونه از ماژول مشترک بارگذاری شده و بین همه برنامه ها به اشتراک گذاشته شود.


بارگذاری مجدد داغ

برای فعال کردن بارگذاری مجدد داغ سرور گره (نه کلاینت) در تولید، باید ابزار اعتبار مجدد را به document.js_ اضافه کنید. بدون آن توصیه می شود، سرورها نمی توانند به روز رسانی های راه دور را بدون راه اندازی مجدد کامل انجام دهند.

import { revalidate, FlushedChunks, flushChunks }from '@module-federation/nextjs-mf/utils';
import Document, { Html, Head, Main, NextScript } from 'next/document';

class MyDocument extends Document {
  static async getInitialProps(ctx) {
    if(process.env.NODE_ENV === "development" && !ctx.req.url.includes("_next")) {
      await revalidate().then((shouldReload) =>{
        if (shouldReload) {
          ctx.res.writeHead(302, { Location: ctx.req.url });
          ctx.res.end();
        }
      });
    } else {
      ctx?.res?.on("finish", () => {
        revalidate()
      });
    }

    const chunks = await flushChunks()

    const initialProps = await Document.getInitialProps(ctx);
    return {
      ...initialProps,
      chunks
    };
  }

  render() {
    return (
      <Html>
        <Head>
          <FlushedChunks chunks={this.props.chunks} />
        </Head>
        <body>
        <Main />
        <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;

چرا به Micro-Frontend نیاز دارید؟

سازمان شما با استفاده از اهداف توسعه پروژه micro-frontend شما سرعت بازگشت سرمایه (ROI) این استراتژی جدید را به حداکثر خواهد رساند. با این حال، اگر هنوز مطمئن نیستید که چرا باید به استفاده از micro-frontends فکر کنید، وقت آن است که مزایای استفاده از Micro-frontends را در نظر بگیرید:


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


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


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


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


4. تست آسان
بهتر است قبل از شروع تست ادغام، اجزای برنامه جداگانه را آزمایش کنید. Micro-frontend این کار را امکان پذیر می کند! تیم‌ها قبل از برنامه، micro-frontend را آزمایش می‌کنند و احتمال ورود اشکالات به سیستم زنده را کاهش می‌دهند. مزایای اضافی شامل یک پایگاه کد کوچک و قابل مدیریت و امکان افزودن یا حذف هر ماژول از سیستم است.

نتیجه

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

توانایی تقسیم یک برنامه واحد به چندین مؤلفه که می توانند به صورت جداگانه توسعه داده شوند، نگهداری و مستقر شوند، مزیت اضافه این روش است. Micro-frontend یک مفهوم پیشرفته با برخی ویژگی های هیجان انگیز است که می توان از آنها استفاده کرد.

#میکرو_فرانت_اند#فرانت_اند#react#react_mircofronend#microfrontend#next.js#nextjs#module_federation
نظرات ارزشمند شما :

در حال دریافت...

مقاله های مشابه

در حال دریافت...