پرش به مطلب اصلی

ساختار دایرکتوری (Directory Structure)

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

هدف از این ساختار، ایجاد نظمی است که:

  • توسعه را ساده‌تر کند
  • وابستگی‌ها را شفاف نگه دارد
  • مقیاس‌پذیری پروژه را تضمین کند
  • و همکاری تیمی را بدون تداخل ممکن سازد

در این معماری، ساختار پوشه‌ها بر اساس مسئولیت (Responsibility) و دامنه‌ی منطقی (Domain) شکل می‌گیرد، نه صرفاً نوع فایل‌ها.


چرا ساختار دایرکتوری مهم است؟

در پروژه‌های کوچک، ساختار پوشه‌ها شاید اهمیت زیادی نداشته باشد؛ اما در پروژه‌های متوسط و بزرگ، یک ساختار اشتباه می‌تواند باعث:

  • افزایش وابستگی‌های پنهان
  • پیچیدگی در توسعه ویژگی‌های جدید
  • دشواری در تست و نگهداری
  • و کاهش خوانایی کد شود

به همین دلیل، ساختار این پروژه به‌گونه‌ای طراحی شده که:

هر قابلیت (Feature) یا دامنه‌ی منطقی، جای مشخص، مستقل و قابل پیش‌بینی در پروژه داشته باشد.


الگوی ساختار دایرکتوری - Route Colocation

در این پروژه، ساختار دایرکتوری بر اساس الگوی Route Colocation در Next.js طراحی شده است.

Route Colocation رویکردی است که در مستندات رسمی Next.js نیز توصیه شده و بر این اصل استوار است که کدهای مرتبط با یک مسیر (Route) در کنار همان مسیر نگهداری شوند. به این معنی که کامپوننت‌ها، هوک‌ها، سرویس‌ها، اسکیماها و سایر وابستگی‌های مرتبط با یک صفحه یا قابلیت، تا حد ممکن در همان محدوده‌ی مسیر قرار می‌گیرند.

این رویکرد باعث می‌شود:

  • وابستگی‌های هر بخش در نزدیک‌ترین محل ممکن قرار بگیرند
  • درک ساختار پروژه برای توسعه‌دهندگان ساده‌تر شود
  • توسعه و نگهداری ویژگی‌ها مستقل‌تر انجام شود

این الگو با اصل ماژولاریتی که در معماری این پروژه تعریف شده هم‌راستا است؛ زیرا هر مسیر عملاً به یک ماژول مستقل از نظر مسئولیت تبدیل می‌شود که منطق و وابستگی‌های خود را در کنار هم نگه می‌دارد.

علاوه بر این، برای جلوگیری از تبدیل شدن فایل‌های داخلی به Route، از Private Folder Convention در Next.js استفاده می‌کنیم. در این روش، پوشه‌هایی که با _ شروع می‌شوند به عنوان پوشه‌های خصوصی در نظر گرفته می‌شوند و توسط سیستم Routing ایندکس نمی‌شوند. این کار به ما اجازه می‌دهد منطق داخلی، زیرماژول‌ها و ابزارهای مرتبط با یک مسیر را در همان محدوده نگه داریم بدون اینکه در ساختار URL یا Routing برنامه تأثیر بگذارند.

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


ساختار کلی پروژه

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

در ادامه، نمای کلی دایرکتوری‌ها آورده شده است:

├── public
│ ├── audios
│ ├── documents
│ ├── fonts
│ ├── icons
│ ├── images
│ └── videos
└── src
├── actions
├── api
├── app
├── components
├── configs
├── constants
├── enums
├── hooks
├── libraries
├── stores
├── styles
├── types
└── utilities

Public

پوشه public محلی است برای نگهداری فایل‌های استاتیک اپلیکیشن؛ فایل‌هایی که باید بدون پردازش و مستقیماً توسط مرورگر در دسترس باشند. Next.js این دایرکتوری را به‌عنوان ریشه‌ی منابع استاتیک در نظر می‌گیرد و هر فایلی که در این پوشه قرار دارد، از طریق مسیر / در زمان اجرا قابل دسترسی است.

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

در ادامه، زیرپوشه‌های اصلی پوشه public و کاربرد آن‌ها معرفی می‌شوند.

Audios

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

Documents

پوشه documents مخصوص فایل‌های دانلودی مثل PDF، DOCX، ZIP و سایر اسناد است. فایل‌هایی که کاربر باید دانلود کند یا مستقیماً مشاهده کند، در این بخش نگهداری می‌شوند. هدف از این جداسازی، ایجاد نقطه‌ای مشخص برای منابع اسنادی و جلوگیری از پراکندگی آن‌هاست.

Fonts

پوشه fonts برای نگهداری فونت‌های سفارشی استفاده می‌شود. استفاده از این دایرکتوری امکان بارگذاری مستقیم فونت‌ها از طریق CSS یا Next.js font optimization را فراهم می‌کند. قرار دادن فونت‌ها در public باعث می‌شود مسیر آن‌ها ثابت، ساده و بدون وابستگی به Build Pipeline باشد.

Icons

پوشه icons برای نگهداری آیکون‌های عمومی پروژه استفاده می‌شود؛ مانند آیکون‌های سفارشی طراحی‌شده در Figma، فایل‌های SVG، یا کتابخانه‌هایی مثل Font Awesome. این آیکون‌ها معمولاً در بخش‌های مختلف رابط کاربری استفاده می‌شوند و به‌دلیل ماهیت سبک و تکرارشونده‌ی خود، ساختار و مدیریت متفاوتی نسبت به تصاویر عادی دارند. تفکیک آن‌ها در یک دایرکتوری مستقل باعث می‌شود نگهداری، نسخه‌سازی و استفاده‌ی مجدد از Assetهای رابط کاربری ساده‌تر و استانداردتر باشد.

Images

پوشه images شامل تصاویر عمومی پروژه است؛ مانند لوگوها، آیکون‌ها یا تصاویر ثابت صفحات. این فایل‌ها مستقیماً قابل دسترسی هستند و می‌توانند در کنار next/image برای بهینه‌سازی بارگذاری استفاده شوند. وجود یک محل مرکزی برای تصاویر، مدیریت Assetهای تصویری را استاندارد و پیش‌بینی‌پذیر می‌کند.

Videos

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


Src

پوشه src محل قرارگیری تمام کدهای اصلی اپلیکیشن است. تمام منطق برنامه، کامپوننت‌ها، سرویس‌ها، استورها، هوک‌ها و سایر ساختارهای برنامه در این دایرکتوری سازمان‌دهی می‌شوند.

هدف از قرار دادن کدها در src ایجاد یک مرز مشخص میان کد اپلیکیشن و سایر فایل‌های پروژه (مانند تنظیمات، اسکریپت‌ها یا منابع استاتیک) است. این ساختار باعث می‌شود معماری پروژه خواناتر، قابل نگهداری‌تر و مقیاس‌پذیرتر باشد.

در ادامه، زیرپوشه‌های اصلی پوشه src و کاربرد آن‌ها معرفی می‌شوند.


Actions

پوشه actions شامل Actionهای اشتراکی در سطح اپلیکیشن است.

منظور از Action در این معماری، توابعی هستند که یک فرآیند (Workflow) یا عملیات سطح برنامه (Application-Level Operation) را پیاده‌سازی می‌کنند؛ عملیاتی که ممکن است در سمت Client، Server یا هر دو اجرا شوند و معمولاً از چندین Helper یا سرویس داخلی استفاده کنند.

این Actionها برخلاف لایه api مسئول ارتباط با Backend نیستند و همچنین برخلاف utilities صرفاً توابع کمکی کوچک و بدون وضعیت محسوب نمی‌شوند.

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

برای مثال:

  • مدیریت Session
  • مدیریت Cookieها
  • عملیات Login و Logout
  • Redirectهای سراسری
  • بررسی Permissionها
  • دریافت Access Token
  • عملیات وابسته به محیط (Client / Server)
  • سایر Workflowهای مشترک در سطح اپلیکیشن
├── actions
├── establish-session
├── get-access-token
├── is-user-verified
└── terminate-session

چه زمانی از actions استفاده کنیم؟

هر زمان که یک منطق:

  • در چندین بخش پروژه مورد استفاده قرار گیرد
  • به یک Route یا Feature خاص وابسته نباشد
  • یک عملیات سطح برنامه را پیاده‌سازی کند
  • و در دسته‌بندی api، hooks یا utilities قرار نگیرد

بهتر است در پوشه actions قرار گیرد.

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

تفاوت با سایر لایه‌ها

DirectoryResponsibility
actionsWorkflowها و عملیات سطح اپلیکیشن
apiارتباط با Backend، Query، Mutation و Data Fetching
hooksمنطق قابل استفاده مجدد مبتنی بر React
utilitiesHelper Functionهای عمومی و بدون وابستگی

Api

پوشه api لایه‌ای است که مسئول مدیریت ارتباط با سرور و تمام عملیات مربوط به داده می‌باشد.

این لایه شامل موارد زیر است:

  • Business Logic (در سطح API communication)
  • Communication With Backend
  • Data Fetching
  • Custom Query/Mutation Abstractions
  • Server Actions (If-needed)
  • Data/Response Types

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

معماری کلی

ساختار api در این پروژه بر اساس یک معماری:

  • Domain-Oriented
  • Feature-Based
  • Modular

طراحی شده است.

در این ساختار:

  • هر Domain یک پوشه مستقل دارد
  • هر عملیات یا Feature داخل همان Domain قرار می‌گیرد
  • هر Feature مسئول Query / Mutation / Actions / Types مربوط به خود است

ساختار کلی

├── api
├── auth
| ├── forgot-password
| ├── login
| ├── logout
| ├── refresh-token
| ├── register
| └── verify
└── users
├── bulk-delete
├── compact
├── create
├── delete
├── list
| ├── index.ts
| ├── queries.ts
| └── types.ts
└── update
├── index.ts
├── mutations.ts
└── types.ts

توضیح فایل‌ها

FileResponsibility
index.tsPublic API و re-export
queries.tsتمام useQuery ها
mutations.tsتمام useMutation ها
actions.tsServer Actions و cookie/session helpers
types.tsTypeScript data types و interfaces

مزایای این معماری

این ساختار مزایای زیر را فراهم می‌کند:

  • جداسازی کامل Data Layer از UI
  • استقلال کامل Featureها
  • ماژولار بودن ساختار پروژه
  • قابلیت توسعه بالا
  • تست‌پذیری بهتر
  • جلوگیری از پخش شدن API logic در کل پروژه
  • خوانایی بهتر پروژه‌های بزرگ
  • مدیریت ساده‌تر Query/Mutationها
  • قابلیت حذف یا توسعه Featureها بدون تاثیر روی سایر بخش‌ها
مهم

در این پروژه از فایل request.ts استفاده نمی‌شود.

دلیل این تصمیم:

  • وجود abstractionهای داخلی
  • تنظیمات اختصاصی dorapi
  • جلوگیری از abstraction اضافی
  • ساده‌تر شدن debugging
  • شفاف‌تر شدن flow درخواست‌ها

به همین دلیل، API callها مستقیماً داخل query.ts و mutation.ts نوشته می‌شوند.


App

پوشه app هسته‌ی سیستم Routing در Next.js است. تمام مسیرهای برنامه، layoutها، صفحه‌ها و فایل‌های خاص Next.js مانند page.tsx، layout.tsx، not-found.tsx و ... در این بخش تعریف می‌شوند.

در این پروژه، وابستگی‌ها، ماژول‌ها و منطق مرتبط با هر Route در نزدیک‌ترین محل ممکن به همان مسیر نگهداری می‌شوند. به همین دلیل، هر مسیر می‌تواند شامل پوشه‌های private، ساب ماژول‌ها، کامپوننت‌ها، هوک‌ها، تایپ‌ها و سایر اجزای وابسته به خود باشد.

برای مثال:

├── about-us
├── _page
| ├── HeroSection
| | ├── Component.tsx
| | ├── index.ts
| | └── types.ts
| ├── OurServices
| | ├── Component.tsx
| | ├── index.ts
| | └── types.ts
| ├── ContactUs
| | ├── Component.tsx
| | ├── index.ts
| | └── types.ts
| ├── use-logic
| | ├── hook.ts
| | ├── index.ts
| ├── constants.ts
| ├── index.ts
| └── types.ts
├── some-internal-page
| └── page.tsx
└── page.tsx

در این ساختار:

  • فایل page.tsx نقطه‌ی ورود Route است.
  • تمام ماژول‌ها، سکشن‌ها و منطق صفحه در پوشه _page قرار می‌گیرند.
  • page.tsx وابستگی‌ها و زیرماژول‌های مورد نیاز خود را از همین مسیر import می‌کند.
  • پوشه _page یک Private Folder محسوب می‌شود.

در Next.js، پوشه‌هایی که با _ شروع می‌شوند توسط سیستم Routing ایندکس نمی‌شوند.

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

نکته

این الگو فقط به page.tsx محدود نیست.

در صورت نیاز، می‌توان برای layout.tsx، not-found.tsx، loading.tsx، error.tsx و سایر فایل‌های خاص Next.js نیز از همین ساختار استفاده کرد.

یعنی منطق، ماژول‌ها و اجزای مرتبط با هرکدام را در یک private folder مرتبط قرار داد.

این رویکرد باعث می‌شود:

  • ساختار هر Route به صورت self-contained باشد
  • وابستگی‌ها در نزدیک‌ترین محل ممکن قرار بگیرند
  • و مقیاس‌پذیری پروژه در طول زمان حفظ شود

Components

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

ساختار کلی این پوشه به شکل زیر است:

├── components
├── boundaries
├── common
├── containers
├── features
├── icons
└── kits

در ادامه، زیرپوشه‌های اصلی پوشه components و کاربرد آن‌ها معرفی می‌شوند.

Boundaries

این بخش شامل Boundaryهای عمومی و سراسری رابط کاربری است.

کامپوننت‌هایی که برای مدیریت وضعیت‌های خاص در لایه نمایش استفاده می‌شوند و معمولاً در نقاط مختلف پروژه قابل استفاده هستند.

برای مثال:

  • EmptyBoundary
  • ErrorBoundary
  • HydrationBoundary
  • FallbackBoundary

این کامپوننت‌ها معمولاً مسئول مدیریت وضعیت‌هایی مانند خطا، خالی بودن داده، fallback UI یا تفاوت‌های hydration بین سرور و کلاینت هستند.

Common

پوشه common شامل کامپوننت‌های پایه و reusable پروژه است.

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

برای مثال:

  • Button
  • Accordion
  • Tabs

این کامپوننت‌ها معمولاً مستقل از منطق یک صفحه یا یک Route خاص هستند و نقش building blockهای اصلی رابط کاربری را دارند.

Containers

پوشه containers برای نگهداری containerهای اشتراکی و سراسری استفاده می‌شود.

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

برای مثال:

  • PageContainer
  • SectionContainer

این لایه کمک می‌کند الگوهای تکرارشونده‌ی layout در سطح پروژه یکپارچه و قابل استفاده‌ی مجدد باقی بمانند.

Icons

از آنجا که پکیج اصلی آیکون‌ها در پروژه‌ها Font Awesome است، آیکون‌های رایج مستقیماً از همان منبع استفاده می‌شوند.

اما اگر در پروژه آیکونی خارج از Font Awesome وجود داشته باشد، یا آیکون سفارشی نیاز باشد، پیاده‌سازی آن به صورت کامپوننت tsx در این پوشه قرار می‌گیرد.

بنابراین، پوشه icons محل نگهداری:

  • آیکون‌های سفارشی
  • آیکون‌هایی خارج از icon pack اصلی پروژه
  • نسخه‌های component-based از آیکون‌ها

است.

Kits

پوشه kits شامل UI kitهای کامل، اشتراکی و کاملاً Presentational است.

یعنی بخش‌هایی از رابط کاربری که از چندین جزء تشکیل شده‌اند، ممکن است منطق نمایشی (UI Logic) مخصوص خود را داشته باشند، و در بیش از یک صفحه یا Route مورد استفاده قرار بگیرند؛ اما هیچ ارتباط مستقیمی با API و دیتای سرور ندارند.

به بیان دیگر، kits فقط شکل و رفتار UI را در خود نگه می‌دارد و داده‌ی مورد نیاز خود را از طریق Props از بیرون دریافت می‌کند، نه از طریق Fetch یا Query مستقیم.

برای مثال:

  • یک BlogCard که عنوان، تصویر و خلاصه را به‌عنوان Prop می‌گیرد و در چند صفحه مختلف نمایش داده می‌شود
  • یک ListFooter که شامل Pagination، Page Size Selector و وضعیت (Status) است، اما state و داده‌ی آن از کامپوننت والد کنترل می‌شود
  • یک Hero Section که هم در صفحه Landing و هم در صفحه about-us استفاده شود
  • یک Contact Us Form که Submit آن توسط والد مدیریت می‌شود، نه توسط خود کامپوننت

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

به همین دلیل، این نوع UIهای اشتراکی در پوشه kits قرار می‌گیرند.

به طور کلی، kits برای بخش‌هایی استفاده می‌شود که:

  • shared هستند
  • فقط به یک Route تعلق ندارند و در چند Route مختلف استفاده می‌شوند
  • ترکیبی از چند جزء UI هستند
  • هیچ‌گونه API Call، Query یا Mutation مستقیمی ندارند

این تفکیک باعث می‌شود مرز بین:

  • کامپوننت‌های عمومی کوچک در common
  • containerهای ساختاری در containers
  • بخش‌های کامل‌تر و چندبخشی اما کاملاً Presentational در kits
  • و بخش‌های کامل، متصل به سرور و دارای منطق داده در features

به‌صورت شفاف حفظ شود.

Features

پوشه features شامل بخش‌های کامل و اشتراکی رابط کاربری است که علاوه بر UI، منطق داده (Data Logic) و ارتباط مستقیم با API را نیز در خود نگه می‌دارند.

برخلاف kits که صرفاً Presentational است و داده‌ی خود را از Props می‌گیرد، یک Feature خودش مسئول Fetch کردن، Mutate کردن و مدیریت کامل چرخه‌ی داده‌ی خود است. به همین دلیل، یک Feature را می‌توان مستقل، Self-Contained و قابل استفاده در چندین Route، بدون نیاز به دریافت داده از بیرون، در نظر گرفت.

برای مثال:

  • یک ProfileTable که شامل جدول کاربران، فرآیند Add، Edit و Delete است و در صفحه Dashboard و صفحه Settings استفاده می‌شود
  • یک CommentsSection که خودش Comment‌ها را Fetch می‌کند، امکان ارسال، ویرایش و حذف Comment را فراهم می‌کند و در چند صفحه مختلف محصول استفاده می‌شود
  • یک NotificationsPanel که خودش به API متصل است، وضعیت خوانده‌شده/نخوانده را مدیریت می‌کند و در بیش از یک Layout استفاده می‌شود
نکته

واژه‌ی Feature در اینجا با Feature تعریف‌شده در لایه api (مثل users/create یا auth/login) متفاوت است. در لایه api، Feature به یک عملیات مشخص (Query یا Mutation) اشاره دارد؛ اما در اینجا، یک Feature ممکن است از چند Feature لایه api به‌صورت ترکیبی استفاده کند (مثلاً create، update و delete را با هم در خود جای دهد).

ساختار داخلی یک Feature معمولاً به‌صورت زیر است:

├── features
└── ProfileTable
├── AddForm
| ├── Component.tsx
| └── index.ts
├── EditForm
| ├── Component.tsx
| └── index.ts
├── Delete
| ├── Component.tsx
| └── index.ts
├── use-table
| ├── hook.ts
| └── index.ts
├── Component.tsx
├── index.ts
└── types.ts

به طور کلی، features برای بخش‌هایی استفاده می‌شود که:

  • shared هستند و در بیش از یک Route استفاده می‌شوند
  • ترکیبی از چند جزء UI هستند
  • خودشان مستقیماً با API ارتباط دارند (Query / Mutation)
  • چندین Workflow یا Flow کامل (مثل Add، Edit، Delete) را در خود جای داده‌اند
  • مستقل از Route و Self-Contained هستند

Configs

پوشه configs شامل تنظیمات و پیکربندی‌های سطح پروژه است.

هر نوع configuration که به ساختار کلی برنامه مربوط باشد و به یک Route یا Feature خاص تعلق نداشته باشد، در این بخش قرار می‌گیرد.

برای مثال:

  • تنظیم فونت‌ها با استفاده از localFont
  • تنظیمات مربوط به Sentry
  • کانفیگ ابزارهای جانبی
  • تنظیمات سراسری کتابخانه‌ها

این پوشه محل متمرکز نگهداری تنظیمات زیرساختی پروژه است.


Constants

پوشه constants شامل مقادیر ثابت (Static Values) اشتراکی در سطح اپلیکیشن است.

هر مقداری که:

  • در چندین بخش برنامه استفاده شود
  • تغییرپذیر نباشد
  • و به منطق یک Route و یا ماژول خاص وابسته نباشد

در این بخش نگهداری می‌شود.

این کار باعث جلوگیری از تکرار مقادیر ثابت در نقاط مختلف پروژه می‌شود.


Enums

پوشه enums شامل Enumهای اشتراکی در سطح اپلیکیشن است.

هر Enum که در چندین ماژول یا Feature مورد استفاده قرار بگیرد، در این بخش تعریف می‌شود تا:

  • از تکرار جلوگیری شود
  • یک منبع واحد برای مقادیر ثابت نوعی (Type-safe) وجود داشته باشد
  • خوانایی و انسجام کد افزایش یابد

Hooks

پوشه hooks شامل Custom Hookهای اشتراکی مرتبط با منطق داخلی است.

این بخش مخصوص Hookهایی است که:

  • به یک Route خاص تعلق ندارند
  • در چندین بخش پروژه استفاده می‌شوند
  • مربوط به منطق (logic) هستند، نه API Call یا Service Layer

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


Libraries

پوشه libraries شامل سفارشی‌سازی‌ها، abstractionها و تنظیمات مربوط به پکیج‌های خارجی است.

هر بخشی که:

  • مستقیماً به یک پکیج خارجی مربوط باشد
  • یا یک لایه abstraction روی آن ایجاد کند
  • و در ساختار سایر پوشه‌ها جای مشخصی نداشته باشد

در این بخش قرار می‌گیرد.

برای مثال:

  • http-client
  • تنظیمات یا تایپ‌های سفارشی tanstack-query
  • ساختارهای مربوط به validation
  • wrapperها یا adapterهای مربوط به کتابخانه‌ها

این لایه باعث می‌شود وابستگی‌های خارجی در یک نقطه متمرکز و قابل مدیریت باقی بمانند.


Stores

پوشه stores شامل مدیریت state سراسری پروژه است.

در این پروژه، مدیریت state گلوبال با استفاده از Zustand انجام می‌شود.

هر state که:

  • در چندین Route استفاده شود
  • یا ماهیت global داشته باشد

در این بخش تعریف می‌شود.


Styles

پوشه styles مسئول نگهداری و سازماندهی تمام استایل‌های سراسری پروژه است.

ساختار این پوشه به‌صورت آگاهانه مشابه ساختار components طراحی شده تا بین لایه UI و لایه Style انسجام و قابلیت نگهداری حفظ شود. به این معنا که هر Component می‌تواند ساختار استایل متناظر و قابل پیش‌بینی خود را نیز در همین معماری داشته باشد.

این پوشه معمولاً شامل استایل‌هایی است که:

  • بین چند بخش مختلف پروژه مشترک هستند
  • وابسته به Route خاصی نیستند
  • یا خارج از الگوی Route Colocation قرار می‌گیرند

ساختار کلی

styles/
├── components/
├── tailwind/
├── vendors/
└── index.css

Components

پوشه components در بخش styles دقیقاً ساختاری مشابه پوشه components اصلی پروژه دارد.

هدف این ساختار:

  • حفظ ارتباط مستقیم بین Component و Style
  • پیدا کردن سریع استایل‌های مرتبط
  • جلوگیری از پراکندگی فایل‌های استایل
  • و افزایش مقیاس‌پذیری پروژه در بلندمدت است
ساختار
├── components
├── boundaries
├── common
├── button
├── index.css
├── containers
├── icons
├── kits
└── index.css

این ساختار باعث می‌شود توسعه‌دهنده بتواند به‌راحتی مسیر استایل هر بخش از UI را حدس بزند و مدیریت کند.

Tailwind

پوشه tailwind شامل تنظیمات، توکن‌ها، utilityها و ساختارهای مرتبط با Tailwind CSS است.

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

  • Theme Configuration
  • Design Tokens
  • Utility Layers
  • Custom Variants
  • Plugin Configurations
  • و ساختارهای کمکی مرتبط با Design System

در این بخش نگهداری می‌شوند.

هدف این لایه، متمرکز نگه داشتن تمام تنظیمات مربوط به Tailwind و جلوگیری از پراکندگی Configurationها در سطح پروژه است.

Vendors

پوشه vendors برای نگهداری استایل‌ها و منابع مربوط به کتابخانه‌ها و پکیج‌های خارجی استفاده می‌شود.

برای مثال:

  • Override کردن استایل کتابخانه‌ها
  • فایل‌های CSS خارجی
  • فونت‌ها یا منابع استایل شخص ثالث
  • یا هر Style Dependency خارجی

در این بخش قرار می‌گیرند.

این جداسازی باعث می‌شود مرز بین استایل‌های داخلی پروژه و منابع Third-party کاملاً شفاف باقی بماند.

index.css

فایل index.css نقطه ورود اصلی استایل‌های اپلیکیشن محسوب می‌شود و در layout.tsx ایمپورت می‌شود.

این فایل معمولاً مسئول:

  • Import کردن لایه‌های اصلی استایل
  • تعریف Global Styles
  • راه‌اندازی Tailwind Layers
  • Normalize / Reset
  • و تعریف CSS Variableهای سراسری پروژه است

به‌عبارت دیگر، index.css ریشه سیستم استایل پروژه محسوب می‌شود.


Types

پوشه types شامل Typeهای اشتراکی در سطح اپلیکیشن است.

هر Type که:

  • در چندین بخش برنامه استفاده شود
  • و به یک Route خاص وابسته نباشد

در این بخش تعریف می‌شود.

این کار باعث افزایش انسجام Type System و جلوگیری از تعریف تکراری typeها می‌شود.


Utilities

پوشه utilities شامل توابع کمکی داخلی پروژه است.

هر Helper Function که:

  • عمومی باشد
  • در چندین بخش استفاده شود
  • و به یک Feature خاص محدود نباشد

در این بخش قرار می‌گیرد.

این توابع معمولاً شامل ابزارهای پردازشی، formatterها، helperهای منطقی و ابزارهای کوچک داخلی هستند.


جمع‌بندی معماری ساختار پروژه

ساختار این پروژه بر اساس یک اصل ساده اما مهم طراحی شده است:

هر چیزی که به یک Route مشخص تعلق دارد، در کنار همان Route قرار می‌گیرد. هر چیزی که در چندین بخش پروژه استفاده می‌شود، در لایه‌های اشتراکی موجود در (src/*) قرار می‌گیرد.

به بیان دیگر:

  • لایه app محل پیاده‌سازی Route Colocation است.
  • لایه‌های دیگر موجود در سطح src محل نگهداری Shared Resources هستند.

این تفکیک باعث می‌شود:

  • هر Route ساختاری self-contained داشته باشد
  • وابستگی‌ها تا حد ممکن محلی بمانند
  • shared code به‌صورت شفاف و قابل مدیریت نگهداری شود
  • و پروژه در مقیاس‌های بزرگ دچار درهم‌ریختگی ساختاری نشود

در نهایت، هدف این ساختار:

  • افزایش خوانایی
  • افزایش مقیاس‌پذیری
  • کاهش coupling
  • و حفظ maintainability در طول زمان

است.

این ساختار صرفاً یک چیدمان پوشه‌ها نیست؛ بلکه بازتابی از معماری ماژولار و تفکر domain-oriented در سطح پروژه است.