ساختار دایرکتوری (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هایی است که چندین بخش از سیستم را با یکدیگر هماهنگ میکنند و یک رفتار مشخص را در اختیار سایر قسمتهای پروژه قرار میدهند.
تفاوت با سایر لایهها
| Directory | Responsibility |
|---|---|
actions | Workflowها و عملیات سطح اپلیکیشن |
api | ارتباط با Backend، Query، Mutation و Data Fetching |
hooks | منطق قابل استفاده مجدد مبتنی بر React |
utilities | Helper 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
توضیح فایلها
| File | Responsibility |
|---|---|
index.ts | Public API و re-export |
queries.ts | تمام useQuery ها |
mutations.ts | تمام useMutation ها |
actions.ts | Server Actions و cookie/session helpers |
types.ts | TypeScript 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های عمومی و سراسری رابط کاربری است.
کامپوننتهایی که برای مدیریت وضعیتهای خاص در لایه نمایش استفاده میشوند و معمولاً در نقاط مختلف پروژه قابل استفاده هستند.
برای مثال:
EmptyBoundaryErrorBoundaryHydrationBoundaryFallbackBoundary
این کامپوننتها معمولاً مسئول مدیریت وضعیتهایی مانند خطا، خالی بودن داده، fallback UI یا تفاوتهای hydration بین سرور و کلاینت هستند.
Common
پوشه common شامل کامپوننتهای پایه و reusable پروژه است.
این بخش معمولاً کوچکترین واحدهای عمومی UI را در بر میگیرد؛ اجزایی که میتوانند در قسمتهای مختلف برنامه بارها استفاده شوند.
برای مثال:
ButtonAccordionTabs
این کامپوننتها معمولاً مستقل از منطق یک صفحه یا یک Route خاص هستند و نقش building blockهای اصلی رابط کاربری را دارند.
Containers
پوشه containers برای نگهداری containerهای اشتراکی و سراسری استفاده میشود.
منظور از container در اینجا ساختارهایی است که برای چیدمان، محدودسازی عرض، ساختاردهی صفحه یا گروهبندی سکشنها در بخشهای مختلف پروژه به کار میروند.
برای مثال:
PageContainerSectionContainer
این لایه کمک میکند الگوهای تکرارشوندهی 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 در سطح پروژه است.