فصل ۲۰: ماژولها و ساختاردهی کد در جاوااسکریپت

۱. چرا ماژول؟ (چرا بهتره کد رو بخشبندی کنیم؟)
فرض کن داری یه فروشگاه آنلاین میسازی. اگه همه دستورهای برنامه رو توی یه فایل بنویسی، کد خیلی شلوغ، گیجکننده و سخت برای نگهداری میشه!
به خاطر همین بهتره کدت رو به “بخشهای کوچیکتر” که هرکدوم یه کار مشخص انجام میدن تبدیل کنی.
این بخشهای کوچیک، همون ماژول هستن. ماژول یعنی “بستهی کدی که کار خودش رو انجام میده”.
مزایا:
- کد تمیزتر و مرتبتر میشه
- راحت میشه تکهای رو به پروژه اضافه یا حذف کرد
- میشه بین پروژهها هم کد رو به اشتراک گذاشت
۲. انواع ماژول در جاوااسکریپت
جاوااسکریپت دوتا سیستم ماژول معروف داره:
- CommonJS (برای Node.js کاربرد داره)
- ESModules (ESM) (در مرورگرهای مدرن و فریمورکهای جدید کاربردیه)
الف. CommonJS (در Node.js)
- توی Node.js فایلها رو اینطوری ماژول بندی میکنی:
مثال:
فایل math.js
function add(a, b) {
return a + b;
}
module.exports = { add };
فایل main.js
const math = require('./math');
console.log(math.add(2, 3)); // خروجی: 5
کلمه کلیدی
requireبرای وارد کردن ماژوله وmodule.exportsبرای خروجی گرفتن.
ب. ESModules (در مرورگر و همه جای جدید!)
- برای پروژههای تحت وب و ES6 به بعد، از این روش استفاده کن.
مثال:
فایل math.js
export function add(a, b) {
return a + b;
}
فایل main.js
import { add } from './math.js';
console.log(add(2, 3)); // خروجی: 5
نکته:
- باید توی تگ
<script>بنویسی:<script type="module" src="main.js"></script> - پسوند فایلت حتماً باید .js باشه و آدرسش رو درست بدی.
۳. ساختار فایل پروژه به شکل ماژول
یک پروژه واقعی معمولاً چندتا پوشه و چند فایل داره:
/project-root
/modules
math.js
user.js
main.js
پس به راحتی میتونی تابعها یا کدهای هر بخش رو ماژول بندی و جداگانه نگهداری کنی.
۴. مزایای استفاده از ESModules (ماژولهای مدرن)
- تکه تکه کردن کد و راحتی توسعه
- جلوگیری از تداخل نامها (هر فایل قلمرو خودش رو داره)
- استفاده برای ساخت کتابخانه و کد اشتراکی
- اتوماتیک اجرا شدن به صورت
strict mode
۵. مقایسه CommonJS و ESModules
| ویژگی | CommonJS | ESModules (ESM) |
|---|---|---|
| محل استفاده | Node.js | همه جا (مرورگرها و Node) |
| نحوه وارد کردن | require() | import/export |
| نحوه خروجی دادن | module.exports | export |
| زمان بارگذاری | در زمان اجرا | قبل از اجرا (static) |
۶. یک مثال پروژه کوچک ماژولار
math.js
export function add(a, b) {
return a + b;
}
export function multiply(a, b) {
return a * b;
}
main.js
import { add, multiply } from './math.js';
console.log("جمع:", add(2,3));
console.log("ضرب:", multiply(2,3));
index.html
<script type="module" src="main.js"></script>
۷. جمعبندی این فصل
- کدت رو با ماژولبندی مرتبتر و حرفهایتر مینویسی
- یاد گرفتی چطور توی جاوااسکریپت ماژول بسازی و ازشون استفاده کنی
- تفاوت سیستمهای ماژول (CommonJS و ESModules) رو شناختی
تمرین ساده:
۱. یک فایل math.js بساز و توش تابع add و subtract رو با export خروجی بده.
۲. داخل main.js این توابع رو import کن و جمع و تفریق دو عدد مختلف رو نمایش بده.
اگر به نکتهای برخوردی یا مشکلی داشتی، دقیقا همون مورد رو بنویس تا با هم برطرفش کنیم!
آیا دوست داری درباره ویژگیهای پیشرفتهتر (export default و import as و …) هم توضیح بدم یا وارد فصل بعدی بشیم؟ 🌟
ویژگیهای پیشرفته ماژولها در جاوااسکریپت (ESModules)
۱. export default (خروجی پیشفرض)
گاهی دوست داری فقط یک چیز از ماژولت خارج بشه (مثلاً یک کلاس یا تابع اصلی). برای این کار از export default استفاده میکنی.
مثال:
math.js
export default function add(a, b) {
return a + b;
}
main.js
import add from './math.js';
console.log(add(6, 7));
نکته مهم: هنگام import کردن، نیازی به آکولاد نیست و نامش را خودت تعیین میکنی.
۲. تغییر نام export/import (as)
گاهی اسم تابع یا خروجی با کدت تداخل داره یا دوست داری اسم بهتری بدی. برای این کار از as استفاده میکنی.
مثال:
math.js
export function add(a, b) { return a + b }
export function subtract(a, b) { return a - b }
main.js
import { add as jam, subtract as tafrigh } from './math.js';
console.log(jam(2, 4));
console.log(tafrigh(10, 3));
۳. جمعآوری همه خروجیهای ماژول (import * as …)
اگر میخوای تمام خروجیهای یک ماژول رو با یک اسم مشترک داشته باشی، از * استفاده کن.
مثال:
main.js
import * as math from './math.js';
console.log(math.add(3, 6));
console.log(math.subtract(10, 1));
حالا همه توابع رو با math. میتونی صدا بزنی.
۴. ترکیب export default با export معمولی
میتونی در یک فایل هم خروجیِ پیشفرض داشته باشی و هم خروجیهای اضافی.
مثال:
math.js
export default function multiply(a, b) { return a * b }
export function add(a, b) { return a + b }
export function subtract(a, b) { return a - b }
main.js
import multiply, { add, subtract } from './math.js';
console.log(multiply(2,5));
console.log(add(10,20));
۵. export مستقیم هنگام تعریف (inline export)
لازم نیست حتماً آخر فایل export کنی! میتونی هنگام تعریف تابع یا متغیر از export استفاده کنی.
export const PI = 3.14;
export function pow(a, b) { return a ** b }
۶. نکات مهم در استفاده از ماژولها
- اجرای کدها در ماژول همواره به صورت strict mode انجام میشود (کدها سختگیرانهتر برسی میشوند)
- فایلهایی که export یا import داشته باشند، خودبهخود ماژول محسوب میشوند.
- آدرسدهی دقیق مهم است: پسوند .js را فراموش نکن!
- نمیتوانی
importوexportرا درون شرط یا حلقه بنویسی. - ترتیب import مهم است اگر کدها به هم وابسته باشند (به خصوص در مرورگر).
جمعبندی بخش پیشرفته
- با export default میتوان خروجی اصلی داشت و با import نام آن را دلخواه قرار داد
- برای تغییر نام خروجی یا وارد کردن همه خروجیها از as و * استفاده میشود
- همزمان میتوان چند نوع خروجی داشت
- export میتواند هنگام تعریف هم انجام شود
تمرین پیشنهادی
۱. یک فایل calculator.js بساز و سه تابع add و multiply و یک export default با نام subtract پیادهسازی کن.
۲. بعد با روشهای مختلف (import ، as و *) توی main.js اونها رو تست کن!