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

قواعد نام‌گذاری (Naming Conventions)

این سند مجموعه‌ای از استانداردهای نام‌گذاری در پروژه‌های مبتنی بر Next.js را تعریف می‌کند.

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

این استانداردها با تمرکز بر موارد زیر طراحی شده‌اند:

  • افزایش خوانایی و وضوح کد
  • کاهش ابهام و پیچیدگی در ساختار پروژه
  • یکپارچگی در سبک کدنویسی بین اعضای تیم
  • ساده‌تر شدن فرآیند نگهداری و توسعه
  • بهبود مقیاس‌پذیری (Scalability) در پروژه‌های بزرگ

اصول عمومی نام‌گذاری

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

یکپارچگی در نام‌گذاری

در بسیاری از موارد ممکن است برای یک مفهوم، چند شیوهٔ معتبر برای نام‌گذاری وجود داشته باشد (مانند camelCase یا snake_case)، اما در سطح پروژه تنها یک الگوی مشخص و ثابت باید انتخاب و به‌صورت کامل رعایت شود.

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

مثال: اگر تصمیم پروژه استفاده از camelCase برای نام‌گذاری متغیرها و توابع است، استفاده از snake_case یا سایر سبک‌ها در هر بخش از پروژه مجاز نیست.

شفافیت در نام‌گذاری

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

چند اصل مهم برای انتخاب نام‌های شفاف:

  • نام‌ها باید واضح، توصیفی و غیرمبهم باشند مثال: formatDate() بهتر از fd() است.
  • نام توابع باید نشان‌دهندهٔ عملی که انجام می‌دهند باشد.
  • نام متغیرها باید بیانگر ماهیت داده‌ای که نگهداری می‌کنند باشد.
  • از نام‌های کوتاه، مخفف‌های غیر استاندارد و نامفهوم باید پرهیز شود مگر در موارد کاملاً رایج و پذیرفته‌شده.
  • تفاوت مفاهیم مشابه باید در نام‌گذاری به‌وضوح مشخص شود تا از برداشت اشتباه جلوگیری گردد.

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


نام‌گذاری فایل و پوشه‌ها

برای حفظ یکپارچگی در ساختار پروژه، تمام فایل‌ها و پوشه‌ها باید با سبک kebab-case نام‌گذاری شوند؛ تنها استثنا در این قانون، پوشه‌هایی هستند که یک React Component را نگهداری می‌کنند.

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

کامپوننت‌ها

پوشهٔ مربوط به هر Component باید با PascalCase نام‌گذاری شود.

ساختار استاندارد
Button/
├── Component.tsx
├── index.ts
├── types.ts

قوانین:

  • نام پوشه حاوی کامپوننت ← PascalCase
  • فایل اصلی کامپوننت ← Component.tsx
  • نام تابع یا کامپوننت داخل فایل ← PascalCase
مثال
export const Button = () => {}

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

هوک‌ها

پوشهٔ مربوط به Hook باید با kebab-case و با پیشوند use نام‌گذاری شود.

مثال
use-auth/
├── hook.ts
├── types.ts
├── index.ts

قوانین:

  • نام پوشه ← *-use
  • فایل‌های داخل ماژول ← kebab-case
  • نام Hook داخل فایل ← camelCase
مثال
export const useAuth = () => {}

توابع و ابزارها (Utilities)

پوشه‌های مربوط به توابع کمکی باید با kebab-case نام‌گذاری شوند.

convert-to-array/
to-select-options/

قوانین

  • نام تابع‌ها ← camelCase
  • نام توابع باید از الگوی Verb First پیروی کنند

مثال:

formatDate()
generateSlug()
calculatePrice()
validateForm()

این الگو باعث می‌شود هدف تابع از روی نام آن به‌وضوح مشخص باشد.

متغیرهای ثابت (Constants)

نام ثابت‌ها باید با سبک SCREAMING_SNAKE_CASE نوشته شود.

مثال
MAX_RETRY_COUNT
DEFAULT_LANGUAGE
API_TIMEOUT

این سبک نام‌گذاری کمک می‌کند ثابت‌ها به‌راحتی از سایر متغیرها تشخیص داده شوند.

اینترفیس و تایپ

برای حفظ یکپارچگی در TypeScript، باید بین استفاده از interface و type مرزبندی مشخصی وجود داشته باشد.

در این پروژه، interface صرفاً برای تعریف Props مربوط به React Componentها استفاده می‌شود و تمام ساختارهای تایپی دیگر با type تعریف خواهند شد.

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

Interfaces

استفاده از interface فقط برای Props مربوط به Componentها مجاز است.

فرمت نام‌گذاری
[ComponentName]Props
مثال
interface ButtonProps {}
interface ModalProps {}
interface UserCardProps {}

Types

تمام مدل‌های داده، Aliasها، Unionها، Genericها، Utility Typeها و سایر ساختارهای تایپی باید با type تعریف شوند.

فرمت نام‌گذاری
type Name
مثال
type BlogItem = {}
type BlogDetail = {}
type ApiResponse = {}
type UserRole = 'admin' | 'editor' | 'user'

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

استثناء

در برخی موارد ممکن است نام یک type با نام یک Component، Hook یا سایر Exportهای همان ماژول یکسان باشد. از آنجا که TypeScript اجازه‌ی Export کردن دو شناسه با یک نام را در یک ماژول نمی‌دهد، در این شرایط از پسوند Type استفاده می‌کنیم.

این مورد تنها استثناء قرارداد نام‌گذاری Typeها در پروژه است و صرفاً برای جلوگیری از تداخل نام‌ها استفاده می‌شود.

وجود تداخل با Component
const AddProvinceForm = () => {}

type AddProvinceFormType = {}

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


نحوه نام گذاری متغیرها

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

متغیرهای عمومی

برای نام‌گذاری متغیرها از camelCase استفاده می‌شود. در این روش، کلمهٔ اول با حروف کوچک نوشته می‌شود و ابتدای هر کلمهٔ بعدی با حرف بزرگ شروع می‌شود. این سبک در جاوااسکریپت و تایپ‌اسکریپت بسیار رایج است و خوانایی کد را افزایش می‌دهد.

مثال
const userName = 'Ali'
const totalPrice = 120

متغیرهای منطقی (Boolean Variables)

نام متغیرهای بولی بهتر است به شکلی انتخاب شوند که شبیه یک سؤال منطقی خوانده شوند. معمولاً این متغیرها با کلماتی مثل is، has، can یا should شروع می‌شوند تا مشخص شود مقدار آن‌ها درست یا نادرست است.

مثال
isLoading
hasPermission
canEdit
shouldRender

برای مثال، وقتی متغیری به نام isLoading می‌بینیم، به‌صورت طبیعی می‌توان آن را این‌گونه خواند:

«آیا در حال بارگذاری است؟»

آرایه‌ها

برای نام‌گذاری آرایه‌ها بهتر است از اسم‌های جمع (plural) استفاده شود. این کار نشان می‌دهد که متغیر شامل چندین مقدار از یک نوع است.

مثال
users
products
categories

هندلرهای رویداد (Event Handlers)

در توابعی که برای مدیریت رویدادها (Event) استفاده می‌شوند، معمولاً از پیشوند handle استفاده می‌شود. این کار باعث می‌شود فوراً مشخص شود که این تابع برای پاسخ به یک رویداد نوشته شده است.

مثال
handleSubmit
handleClick
handleDelete

پرهیز از مخفف کردن کلمات

بهتر است از مخفف کردن کلمات در نام متغیرها خودداری کنید. مخفف‌ها معمولاً خوانایی کد را کاهش می‌دهند و ممکن است برای دیگران قابل‌فهم نباشند.

نمونه نامناسب
usr
prd
cfg
btn
نمونه مناسب
user
product
configuration
button

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


نام‌گذاری API و سرویس‌ها

نام‌گذاری دقیق و استاندارد سرویس‌ها و هوک‌های ارتباط با API، باعث می‌شود که جریان داده‌ها در برنامه قابل‌درک‌تر شود و توسعه‌دهندگان به راحتی متوجه شوند که هر تابع دقیقاً چه عملیاتی را انجام می‌دهد.

استفاده از الگوی نام‌گذاری CRUD

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

مثال
getUsers
getUser
getUserDetail
createUser
updateUser
deleteUser

نام‌گذاری Hookهای Query و Mutation

هنگامی که از کتابخانه‌های مدیریت وضعیت داده‌ها (مانند React Query) استفاده می‌کنید، بهتر است نام‌گذاری هوک‌ها به‌گونه‌ای باشد که هم نوع عمل (Query یا Mutation) و هم ماهیت داده را مشخص کند

مثال
// برای دریافت داده‌ها (Queries)
useGetUsersQuery
useGetUserQuery
useGetUserDetailQuery
// برای تغییر در داده‌ها (Mutations)
useCreateUserMutation
useUpdateUserMutation
useDeleteUserMutation

این سبک نام‌گذاری باعث می‌شود در میان انبوه فایل‌ها و هوک‌ها، به‌سرعت متوجه شوید که با چه نوع عملیاتی طرف هستید.

اجتناب از نام‌های عمومی و مبهم

از به‌کار بردن نام‌های عمومی و مبهم برای توابع خودداری کنید. نام تابع باید به‌طور دقیق هدف و نتیجهٔ عملیات را بیان کند.

نمونه نامناسب (مبهم)
data()
handle()
process()

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

نمونه مناسب (توصیفی)
processPayment()
handleUserDelete()
getDashboardStatistics()

استفاده از نام‌های توصیفی به شما و تیم‌تان کمک می‌کند تا بدون نیاز به خواندن بدنهٔ تابع، متوجه شوید که هر بخش از کد چه مسئولیتی بر عهده دارد.


قرارداد های مخصوص صفحات Next.js

تمام پوشه‌هایی که به‌عنوان route استفاده می‌شوند باید با سبک kebab-case نام‌گذاری شوند. در این سبک، کلمات با خط تیره (-) از هم جدا می‌شوند.

مثال
app/user-profile/
app/blog-post/
app/payment-history/

استفاده از kebab-case باعث می‌شود مسیرهای URL خواناتر باشند و ساختار routing پروژه یکدست باقی بماند.


جمع‌بندی

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

نام‌گذاری استاندارد در نهایت با چند هدف اصلی تعریف می‌شود:

  • افزایش readability (خوانایی و درک سریع نام‌ها)
  • ایجاد predictability (قابل پیش‌بینی بودن نام‌ها و ساختار آن‌ها)
  • بهبود maintainability (سادگی در فهم و تغییر نام‌ها در طول زمان)
  • فراهم کردن scalability (امکان رشد بدون آشفتگی در naming)

یک پروژهٔ خوب صرفاً پروژه‌ای با قوانین زیاد نیست؛ بلکه پروژه‌ای است که در آن نام‌ها:

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

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