Named Export و Default Export: انتخاب درست معماری ماژول
در درس قبل با نحوهی نوشتاری هر دو نوع export آشنا شدید. در این درس، عمیقتر به تفاوتهای عملی این دو الگو پرداخته میشود: چه زمانی هرکدام مناسبتر است، چگونه میتوان آنها را در یک فایل ترکیب یا export مجدد کرد، و یکی از رایجترین اشتباهاتی که هنگام refactor کردن نام یک default export رخ میدهد.
چرا انتخاب میان این دو الگو اهمیت دارد؟
انتخاب میان named و default export صرفاً یک تفاوت نحوی نیست؛ بلکه مستقیماً روی خوانایی، قابلیت refactor، و تجربهی توسعهدهندگانی که از ماژول شما استفاده میکنند تأثیر میگذارد. این انتخاب باید بر اساس ماهیت واقعی محتوای فایل انجام شود، نه صرفاً بر اساس عادت یا سلیقه.
Named Export: مناسب برای مجموعهای از ابزارهای مستقل
وقتی یک فایل شامل چند تابع یا مقدار مرتبط اما مستقل از هم است—مثل یک فایل utility—معمولاً named export انتخاب طبیعیتری است، چون به توسعهدهنده اجازه میدهد فقط همان بخشهایی را که نیاز دارد import کند:
// فایل validators.js
export function isEmail(value) {
return /\S+@\S+\.\S+/.test(value);
}
export function isPhoneNumber(value) {
return /^09\d{9}$/.test(value);
}
export function isStrongPassword(value) {
return value.length >= 8;
}
// فایل دیگر: فقط یک تابع مورد نیاز است
import { isEmail } from "./validators.js";
Default Export: مناسب برای یک مقدار اصلی و شاخص
وقتی هدف یک فایل، ارائهی یک چیز اصلی—مثل یک کلاس، یک کامپوننت، یا یک تابع مرکزی—است، default export معنای واضحتری منتقل میکند: این فایل «یک چیز» است، نه مجموعهای از ابزارهای پراکنده:
// فایل ShoppingCart.js
export default class ShoppingCart {
constructor() {
this.items = [];
}
addItem(item) {
this.items.push(item);
}
}
خطر پنهان default export: نامگذاری ناسازگار هنگام import
از آنجا که default export با هر نام دلخواهی قابل import است، این انعطاف میتواند در پروژههای بزرگ به ناسازگاری نامگذاری منجر شود؛ یک فایل ممکن است در جاهای مختلف با نامهای کاملاً متفاوت import شود:
در این مثال، هر دو Cart و Basket دقیقاً به همان کلاس ShoppingCart اشاره دارند، اما نامهای متفاوت میتواند خواندن و جستوجوی کد را در پروژههای بزرگ دشوارتر کند. named export این مشکل را ندارد، چون نام باید همیشه (مگر با as صریح) با نام اصلی مطابقت داشته باشد.
ترکیب هر دو الگو در یک فایل
هیچ محدودیتی برای استفادهی همزمان از default export و named export در یک فایل وجود ندارد؛ الگوی رایج این است که مقدار اصلی بهصورت default و مقادیر کمکی مرتبط بهصورت named export ارائه شوند:
// فایل ShoppingCart.js
export const MAX_ITEMS = 50;
export default class ShoppingCart {
addItem(item) {
if (this.items.length >= MAX_ITEMS) {
throw new Error("سبد خرید پر است");
}
this.items.push(item);
}
}
Export مجدد (re-export) برای سازماندهی بهتر
در پروژههای بزرگ، رایج است که یک فایل مرکزی (اغلب index.js) صرفاً export های چند فایل دیگر را دوباره در معرض دید قرار دهد، بدون آنکه لازم باشد آنها را ابتدا import و سپس دوباره export کند:
// فایل index.js
export { isEmail, isPhoneNumber } from "./validators.js";
export { default as ShoppingCart } from "./ShoppingCart.js";
// اکنون فایلهای دیگر میتوانند همهچیز را از یک نقطهی واحد import کنند
import { isEmail, ShoppingCart } from "./index.js";
جدول راهنمای انتخاب
| سناریو | الگوی پیشنهادی |
|---|---|
| فایلی با چند تابع کمکی مستقل (utility) | Named Export |
| فایلی که یک کلاس یا کامپوننت اصلی ارائه میدهد | Default Export |
| فایل مرکزی برای جمعآوری export های چند فایل دیگر | ترکیب Named Export با re-export |
نکات کلیدی
- انتخاب میان named و default export باید بر اساس ماهیت محتوای فایل انجام شود، نه سلیقهی شخصی.
- named export برای مجموعهای از ابزارهای مستقل و default export برای یک مقدار اصلی و شاخص مناسبتر است.
- انعطاف نامگذاری در default export میتواند در پروژههای بزرگ به ناسازگاری نام منجر شود.
- export مجدد (re-export) امکان جمعآوری export های چند فایل در یک نقطهی مرکزی مثل index.js را فراهم میکند.
جمعبندی
تصمیم آگاهانه میان named export و default export، تأثیر مستقیمی بر خوانایی و قابلیت نگهداری بلندمدت یک پروژه دارد. در حالی که named export ثبات نامگذاری را تضمین میکند، default export برای معرفی یک مقدار اصلی و شاخص، معنای روشنتری منتقل میکند. ترکیب این دو الگو با تکنیک export مجدد، ابزار اصلی سازماندهی ماژولها در پروژههای بزرگ جاوااسکریپت است.
