قسمت دوم - ساختار پروژه و معماری پوشهها در Next.js 16
Next.js از مسیریابی مبتنی بر سیستم فایل استفاده میکند، یعنی میتوانید از پوشهها و فایلها برای تعریف مسیرها استفاده کنید.
ساختار پروژه و معماری پوشهها در Next.js 16 برای یک پرتفولیوی واقعی
چرا باید از همان ابتدا به ساختار پروژه فکر کنیم؟
وقتی پروژه کوچک است، تقریبا هر ساختاری جواب میدهد. اما سایتی که قرار است هم پرتفولیو باشد، هم بلاگ، و هم داشبورد مدیریت، خیلی زود بزرگ میشود. اگر از ابتدا پوشهها و فایلها را منطقی نچینیم، بعدا پیدا کردن کدها، توسعه قابلیتهای جدید و نگهداری پروژه سخت میشود.
در این دوره، هدف فقط یاد گرفتن syntax نیست. میخواهیم پروژهای بسازیم که چند ماه بعد هم بتوانیم راحت در آن کار کنیم. به همین دلیل، بعد از ساخت پروژه، یکی از اولین کارهای مهم این است که یک معماری پوشهای واضح برای آن در نظر بگیریم.
App Router چه تغییری در ساختار پروژه ایجاد میکند؟
در Next.js 16 با App Router، ساختار مسیرها تا حد زیادی از روی فایلها و پوشهها ساخته میشود. یعنی معماری پروژه فقط یک تصمیم ظاهری نیست؛ مستقیما روی routing هم اثر میگذارد.
مثلا:
app/page.tsxصفحه اصلی سایت استapp/blog/page.tsxصفحه لیست بلاگ استapp/projects/page.tsxصفحه لیست پروژهها استapp/dashboard/page.tsxصفحه داشبورد است
این مدل باعث میشود ساختار فایلها خیلی مهمتر از پروژههای سنتی باشد. هر پوشه میتواند یک بخش از اپلیکیشن را نمایش دهد، و هر تصمیم اشتباه در اینجا بعدا در کل پروژه پخش میشود.
هدف ما از معماری این پروژه چیست؟
ما میخواهیم ساختاری داشته باشیم که این ویژگیها را داشته باشد:
- خوانا باشد
- مقیاسپذیر باشد
- بین بخش عمومی و ادمین تفکیک ایجاد کند
- برای اتصال به Prisma، فرمها، احراز هویت و CMS آماده باشد
- در زمان رشد پروژه، نیاز به جابهجاییهای سنگین نداشته باشد
پس قرار نیست فقط فایلها را دستهبندی کنیم؛ قرار است برای رشد آینده پروژه تصمیم بگیریم.
دو رویکرد رایج برای ساختاردهی
در پروژههای Next.js معمولا دو رویکرد اصلی میبینیم:
رویکرد اول: ساختار نزدیک به routeها
در این رویکرد، بیشتر کدها نزدیک به همان بخشی قرار میگیرند که استفاده میشوند. مثلا کامپوننتها یا helperهای مخصوص بلاگ نزدیک routeهای بلاگ قرار میگیرند.
مزیتها:
- ساده و سریع است
- برای پروژههای کوچک خوب جواب میدهد
ضعفها:
- وقتی پروژه بزرگ میشود، کدهای reusable و utilityها ممکن است پراکنده شوند
رویکرد دوم: ساختار بر اساس نقش فایلها
در این رویکرد، فایلها بر اساس مسئولیت تفکیک میشوند:
components/lib/actions/schemas/types/app/
مزیتها:
- برای پروژههای متوسط و بزرگ منظمتر است
- پیدا کردن منطقهای مشترک آسانتر میشود
ضعفها:
- اگر بیدقت طراحی شود، ارتباط فایلها با feature اصلی ممکن است کمی مبهم شود
برای پروژه ما کدام بهتر است؟
برای این پروژه، بهترین انتخاب یک رویکرد ترکیبی است. یعنی:
- routeها داخل
app/بمانند - کامپوننتهای reusable بیرون از routeها در پوشههای مشخص قرار بگیرند
- منطقهای مشترک در
lib/جمع شوند - typeها، schemaها و actionها جای مشخص خودشان را داشته باشند
این مدل برای پروژه پرتفولیو + بلاگ + داشبورد خیلی مناسبتر است، چون هم از سادگی App Router استفاده میکنیم و هم از شلوغ شدن بیش از حد پوشه app/ جلوگیری میکنیم.
ساختار پیشنهادی پروژه در Next.js 16
برای این دوره، یک ساختار پیشنهادی معقول میتواند چیزی شبیه این باشد:
my-app/
├── app/
│ ├── page.tsx
│ ├── about/
│ │ └── page.tsx
│ ├── contact/
│ │ └── page.tsx
│ ├── blog/
│ │ ├── page.tsx
│ │ └── [slug]/
│ │ └── page.tsx
│ ├── projects/
│ │ ├── page.tsx
│ │ └── [slug]/
│ │ └── page.tsx
│ ├── dashboard/
│ │ ├── page.tsx
│ │ ├── projects/
│ │ └── posts/
│ ├── login/
│ │ └── page.tsx
│ └── api/
│ └── ...
├── components/
│ ├── layout/
│ ├── shared/
│ ├── blog/
│ ├── projects/
│ └── dashboard/
├── lib/
│ ├── utils.ts
│ ├── prisma.ts
│ ├── auth.ts
│ └── cloudinary.ts
├── actions/
├── schemas/
├── types/
├── public/
├── prisma/
├── proxy.ts
└── package.json
این ساختار نهایی و تغییرناپذیر نیست، اما یک نقطه شروع حرفهای و منعطف است.
نقش هر بخش در این معماری
app/
این پوشه فقط برای routeها و فایلهای مرتبط با routing استفاده میشود. یعنی:
page.tsxlayout.tsxloading.tsxerror.tsxnot-found.tsx- route groupها
- dynamic routeها
- route handlerها
بهتر است منطقهای reusable سنگین را بیدلیل داخل app/ نریزیم.
components/
برای کامپوننتهای UI استفاده میشود. بهتر است این پوشه را هم بینظم نگذاریم. مثلا:
components/shared/برای دکمه، container، section title و چیزهای عمومیcomponents/layout/برای navbar، footer، sidebarcomponents/blog/برای کارت مقاله، لیست پستهاcomponents/projects/برای کارت پروژه، gallerycomponents/dashboard/برای جدولها، فرمها و پنل مدیریت
این تفکیک باعث میشود بعدا اگر بخواهیم یک بخش را بازطراحی کنیم، سریعتر فایلهای مربوط را پیدا کنیم.
lib/
این پوشه معمولا محل utilityها و سرویسهای مشترک است. مثلا:
prisma.tsبرای Prisma Clientauth.tsبرای helperهای احراز هویتcloudinary.tsبرای آپلود فایلutils.tsبرای helper functionهای عمومی
هر چیزی که منطق مشترک پروژه است و به چند بخش مختلف مربوط میشود، معمولا جای خوبی در lib/ دارد.
actions/
اگر از Server Actions استفاده کنیم، داشتن پوشه جدا برای actionها ایده خوبی است. مثلا:
- ساخت پست
- ویرایش پروژه
- حذف مقاله
- ورود ادمین
این کار باعث میشود منطق عملیاتها از UI جدا بماند.
schemas/
برای schemaهای Zod خیلی مناسب است. مثلا:
login-schema.tsproject-schema.tspost-schema.ts
این پوشه کمک میکند validationها پراکنده نشوند و فرمها ساختار مشخصی داشته باشند.
types/
اگر typeهای مشترک یا interfaceهای قابل استفاده مجدد داشته باشیم، اینجا نگه میداریم. مثلا:
- type مربوط به
Project - type مربوط به
Post - type مربوط به فرمها یا پاسخهای API
prisma/
این پوشه معمولا شامل فایل schema دیتابیس است:
schema.prisma
بعدا وقتی مدلهای Post، Project و AdminUser را تعریف کنیم، این پوشه اهمیت زیادی پیدا میکند.
public/
برای assetهای عمومی:
- تصاویر
- آیکنها
- فایلهای static
مثلا عکس پروفایل، تصویر hero، placeholderها و faviconها.
proxy.ts
در Next.js 16، چیزی که قبلا با نام middleware شناخته میشد، به proxy تغییر نام داده است. پس اگر بخواهیم قبل از کاملشدن request منطق خاصی اجرا کنیم، باید از فایل proxy.ts در ریشه پروژه استفاده کنیم.
کاربردهای معمول آن:
- redirect کردن کاربر بر اساس وضعیت ورود
- محافظت اولیه از مسیرهای داشبورد
- rewrite یا redirectهای شرطی
- تنظیم بعضی headerها یا cookieها
یک نکته مهم این است که proxy.ts جای منطق سنگین، session management کامل یا data fetching کند نیست. در Next.js 16 این قابلیت بیشتر برای منطق سبک و نزدیک به مرز request در نظر گرفته میشود، نه برای اینکه تمام سیستم auth را فقط داخل آن پیاده کنیم.
آیا از src/ استفاده کنیم؟
Next.js از هر دو حالت پشتیبانی میکند:
- بدون
src/ - با
src/
اگر پروژه را با src/ بسازی، بیشتر فایلهای اپ داخل src/ قرار میگیرند:
src/app/
src/components/
src/lib/
src/proxy.ts
مزیت src/
- ریشه پروژه خلوتتر میشود
- فایلهای config از فایلهای اپلیکیشن جدا میشوند
مزیت نداشتن src/
- ساختار سادهتر و مستقیمتر است
- برای آموزش و شروع کار، خواناتر است
برای این دوره، چون میخواهیم مفاهیم را شفاف و مرحلهای پیش ببریم، فعلا بدون src/ جلو میرویم. اگر بعدا نیاز باشد، مهاجرت به src/ سخت نیست.
چه چیزهایی را نباید داخل app/ شلوغ کنیم؟
یکی از اشتباههای رایج این است که همه چیز را داخل app/ بریزیم فقط چون routeها آنجاست. بهتر است این موارد را تا جای ممکن بیرون از app/ نگه داریم:
- utility functionهای عمومی
- schemaهای validation
- typeهای مشترک
- clientهای سرویسها مثل Prisma
- helperهای auth
- کامپوننتهای reusable که به چند route مربوطاند
این تصمیم از همان ابتدا جلوی آشفتگی را میگیرد.
نامگذاری پوشهها و فایلها
در پروژههای واقعی، نامگذاری خیلی مهم است. بهتر است:
- اسم پوشهها شفاف و کوتاه باشد
- routeها با URL نهایی هماهنگ باشند
- کامپوننتها اسم توصیفی داشته باشند
- فایلهای schema، action و util قابل حدس باشند
مثلا:
project-card.tsxpost-list.tsxcreate-project.tslogin-schema.ts
و در Next.js 16 هم بهتر است از نامگذاریهای جدید و رسمی خود framework استفاده کنیم؛ مثلا بهجای middleware.ts از proxy.ts.
یک قانون مهم برای این پروژه
در این دوره، یک قانون ساده داریم:
هر فایل باید دلیل روشنی برای محل قرارگیری خود داشته باشد.
اگر ندانستی فایلی را کجا بگذاری، از خودت بپرس:
- آیا این فایل route است؟
- آیا UI reusable است؟
- آیا منطق مشترک است؟
- آیا validation است؟
- آیا مربوط به دیتابیس است؟
- آیا مربوط به لایه
proxyاست؟ - آیا مربوط به یک feature خاص است؟
با همین چند سوال، بیشتر تصمیمها روشن میشود.
جمعبندی
در این پست یاد گرفتیم که:
- معماری پوشهها در Next.js 16 مستقیما روی توسعه پروژه اثر میگذارد
- App Router باعث میشود ساختار فایلها اهمیت بیشتری پیدا کند
- برای پروژه پرتفولیو، بلاگ و داشبورد، یک ساختار ترکیبی بهترین انتخاب است
- پوشههایی مثل
app/،components/،lib/،actions/،schemas/،types/وprisma/هرکدام نقش مشخصی دارند - در Next.js 16 باید از
proxy.tsاستفاده کنیم، نهmiddleware.ts - از همان ابتدا باید بین routeها، UI، منطق، validation و request-level logic مرزبندی داشته باشیم
در پست بعدی، میرویم سراغ مسیریابی در App Router و اولین routeهای واقعی سایت مثل صفحه اصلی، درباره من، تماس، پروژهها و بلاگ را میسازیم.