نامگذاری مبتنی بر دامنه کانستنت‌ها در جاوااسکریپت


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

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

مشکلاتی که بدون ساختار بودن کانستنت‌ها می‌تونست برامون به وجود بیاره، موارد زیر بودن:

  • سخت شدن توسعه (اضافه کردن و یا ادیت کردن کانستنت‌ها)
  • مشخص نبودن دامین و منطق کانستنت
  • مشخص نبودن ساختار دیتای کانستنت
  • بوجود آمدن duplication

مزیت‌های داشتن ساختار عبارتند از:

  • ساده کردن توسعه کانستنت‌ها : پروژه به دامین‌های منطقی تقسیم میشه و هر کانستنت جدید متعلق به یک دامین خواهد بود
  • جلوگیری از duplication : یونیک شدن نام کانستنت‌ها
  • مشخص بودن دامنه کانستنت‌ها : منطق و مقدار قابل پیشبینی هر کانستنت از نامش مشخص میشه
  • مشخص بودن نوع مقدار ذخیره شده : تعریف کردن کانستنت‌ها به دو شکل مختلف به منظور مشخص کردن نوع دیتای ذخیره شده

پیاده‌سازی

ما می خواستیم در دو مرحله این کار رو ممکن کنیم و برای کانستنت‌هامون یک ساختار شسته رفته داشته باشیم:

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

بریم ببینیم داستان چی بود!

مرحله اول

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

constants
└── ├── domain-1-1
│ ├── domain-2-1
│ └── domain-2-1
├── domain-1-2
│ ├── domain-2-1
│ └── domain-2-1
| ├── domain-3-1
│ └── domain-3-2
└── domain-1-3
└── domain-2-1
└── domain-3-1

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

بر اساس تجربه ما در ازکی پیشنهاد میشه که بیشتر از ۳ سطح دامنه‌هارو خورد نکنیم، جلوتر میگم چرا!

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

constants
└── ├── order
│ ├── status
│ └── tag
├── customer
│ ├── info
│ └── purchase
| ├── done
│ └── undone
└── product
└── category
├── phone
├── tablet
└── laptop

بخشی از ساختار مورد انتظارمون برای این محصول میتونه این شکلی باشه (بهش صرفا به عنوان یه مثال نگاه کنید)

مرحله اول رو تموم کردیم و تونستیم پروژمون رو به دامین‌های بیزنس لاجیکی تقسیم کنیم.

مرحله دوم

فرض کنید در مثال بالا میخوایم به دسته‌بندی موبایل در زیرمجموعه محصول یک کانستنت‌ اضافه کنیم، پس فایل مقصدمون برای اضافه کردن این کانستنت product -> category -> phone هست.

فقط کافیه از ۲ قانون پیروی کنیم تا به اون چیزی که می‌خوایم برسیم.

قانون اول

نامگذاری : نام کانستنت باید مسیری که فایلمون درش قرار داده شده رو به عنوان پیشوند داشته باشه، مثلا اگر ما می‌خوایم یک کانستنت تحت عنوان brands به این فایل اضافه کنیم، پیشوندهامون به این ۲ شکل میشه (اشکال مختلف رو در قانون دوم میگیم) :

productCategoryPhone یا PRODUCT_CATEGORY_PHONE

قانون دوم

تایپ: برای اینکه بتونیم از اسم کانستنت‌هامون نوع مقداری که درشون هست رو بهتر متوجه بشیم اونا رو به دو دسته تقسیم می‌کنیم، یک دسته primitiveها هستن که برای تعریفشون از SCREAMING_SNAKE_CASE استفاده می‌کنیم و برای non-primitive ها که همون آرایه و آبجکت‌هامون میشن از camelCase استفاده می‌کنیم.

پس برای مثال بالا که می‌خو‌استیم کانستنت brands رو داشته باشیم، مطمئنا باید از camelCase استفاده کنیم و از دو پیشوندی که بالا به دست آوردیم productCategoryPhone رو انتخاب می‌کنیم و در نهایت productCategoryPhoneBrands رو می‌سازیم، کانستنتی که همین الان ساختیم مطمئنا لیستی از برندها خواهد بود، مثل سامسونگ، پس برای تعریف کردن برند سامسونگ هم به راحتی می‌تونیم به PRODUCT_CATEGORY_PHONE_BRAND_SAMSUNG برسیم.

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

مطمئنا متوجه شدین که اسم‌ هامون با پیمایش داخل دامین‌ها بلندتر می‌شن، برای همین توصیه می‌کنم که بیشتر از ۳ سطح دامین نداشته باشیم.

پلاگین

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

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

در نهایت

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


https://www.npmjs.com/package/eslint-plugin-path-dependant-constant-naming
https://github.com/mobinHor/eslint-plugin-path-dependant-constant-naming