بازگشت به وبلاگ
nextjs ۴ دقیقه مطالعه

معماری مقیاس‌پذیر برای پروژه‌های Next.js

ساختار پوشه، مرزبندی ماژول‌ها، مدیریت state، تست، و تصمیم‌های معماری که باعث می‌شوند پروژه Next.js با رشد تیم از هم نپاشد.

تیم ابران
یادداشت‌های محصول و زیرساخت · ۲۵ مرداد ۱۴۰۵
معماری مقیاس‌پذیر برای پروژه‌های Next.js

معماری مقیاس‌پذیر برای پروژه‌های Next.js

پروژه‌های Next.js معمولاً با چند صفحه و چند کامپوننت شروع می‌شوند. در این مرحله تقریباً هر ساختاری کار می‌کند. مشکل وقتی شروع می‌شود که محصول رشد می‌کند: فرم‌ها زیاد می‌شوند، APIها بیشتر می‌شوند، auth پیچیده‌تر می‌شود، تیم بزرگ‌تر می‌شود، و هر تغییر کوچک چند جای برنامه را لمس می‌کند.

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

اول route، بعد feature

در App Router، پوشه app مسئول routing است. بهتر است این پوشه را مرکز کل منطق محصول نکنید. routeها باید composition انجام دهند: داده لازم را بگیرند، layout را انتخاب کنند، و featureهای مناسب را کنار هم بگذارند.

برای مثال:

app/
  (marketing)/
  (dashboard)/
  api/
features/
  billing/
  projects/
  deployments/
components/
  ui/
lib/
  auth/
  api/
  config/

در این مدل، app مسیرها را تعریف می‌کند، اما منطق اصلی هر بخش در feature خودش می‌ماند. این کار پیدا کردن کد، تست‌پذیری، و refactor را ساده‌تر می‌کند.

Route groupها را زود استفاده کنید

Route groupها در Next.js به شما اجازه می‌دهند ساختار داخلی پروژه را بدون تغییر URL مرتب کنید. این قابلیت برای جدا کردن صفحه‌های عمومی، داشبورد، auth، و admin بسیار مفید است.

app/
  (public)/
    page.tsx
    pricing/page.tsx
  (auth)/
    login/page.tsx
    register/page.tsx
  (app)/
    dashboard/page.tsx
    settings/page.tsx

اگر این جداسازی را دیر انجام دهید، معمولاً مجبور می‌شوید layoutها، importها، و state مشترک را دوباره مرتب کنید.

Server Component را پیش‌فرض بگیرید

در Next.js جدید، بهتر است کامپوننت‌ها تا وقتی نیاز واقعی به مرورگر ندارند Server Component بمانند. این کار bundle کلاینت را کوچک‌تر می‌کند، دسترسی به داده را ساده‌تر می‌کند، و جلوی ارسال secret به مرورگر را می‌گیرد.

Client Component را برای این موارد نگه دارید:

  • state تعاملی مثل useState
  • event handlerهایی مثل onClick
  • APIهای مرورگر مثل localStorage
  • فرم‌های بسیار تعاملی
  • real-time subscription در مرورگر

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

منطق دامنه را در کامپوننت دفن نکنید

اگر یک rule محصولی در چند کامپوننت تکرار می‌شود، جای آن در یک helper، service، schema، یا feature module است. کامپوننت باید UI را بسازد، نه اینکه تمام قوانین billing، permission، یا وضعیت lifecycle را خودش حدس بزند.

برای مثال، به جای اینکه هر صفحه جداگانه تشخیص دهد کاربر اجازه deploy دارد یا نه، یک تابع یا hook مشخص داشته باشید که این تصمیم را بر اساس داده معتبر می‌گیرد.

ساختار API و fetch را یکدست کنید

در پروژه‌های بزرگ، پراکندگی fetchها خیلی زود مشکل‌ساز می‌شود. یک بخش با fetch خام کار می‌کند، بخش دیگر با client اختصاصی، و بخش سوم errorها را خودش parse می‌کند.

بهتر است از یک لایه مشترک استفاده کنید:

  • base URL و headerها در یک جا ساخته شوند.
  • خطاها شکل یکسان داشته باشند.
  • cache و revalidation آگاهانه تنظیم شوند.
  • داده‌های public و private با هم قاطی نشوند.

این کار مخصوصاً وقتی چند نفر روی محصول کار می‌کنند، جلوی رفتارهای ناسازگار را می‌گیرد.

تست را نزدیک به ریسک بنویسید

برای هر کامپوننت نیازی به تست سنگین نیست. اما بخش‌هایی مثل schema فرم، permission، محاسبه وضعیت، serialize کردن داده، و مسیرهای auth ارزش تست بالایی دارند. تست‌های کوچک روی این نقاط از بسیاری regressionهای پرهزینه جلوگیری می‌کنند.

چند نقطه خوب برای تست:

  1. validation فرم‌ها
  2. helperهای permission
  3. تبدیل داده API به مدل UI
  4. route guardها
  5. formattingهای وابسته به زبان و جهت متن

جمع‌بندی

معماری خوب در Next.js یعنی تصمیم‌های کوچک ولی پایدار: routeها را از featureها جدا کنید، Server Component را پیش‌فرض بگیرید، منطق دامنه را از UI بیرون بکشید، و fetch و error handling را یکدست کنید. این تصمیم‌ها در پروژه کوچک شاید زیادی دقیق به نظر برسند، اما وقتی محصول رشد کند، همان‌ها سرعت تیم را حفظ می‌کنند.

منبع

#nextjs#architecture#frontend#paas