نظام الوحدات (Modules): تقسيم الكود إلى ملفات قابلة لإعادة الاستخدام


أهلاً بكم أيها المبرمجون الطموحون! اليوم سنتعلم كيفية تنظيم مشاريعنا البرمجية الكبيرة باستخدام نظام الوحدات (Modules) في Node.js، لتقسيم الكود إلى ملفات قابلة لإعادة الاستخدام.

الخطوة الأولى: إنشاء وحدة (Module) وتصدير الدوال

في هذه الخطوة، سنقوم بإنشاء ملف JavaScript يحتوي على مجموعة من الدوال التي نريد استخدامها في أجزاء أخرى من مشروعنا. سنستخدم الكائن module.exports لتصدير هذه الدوال.

// الملف: utils.js

// تعريف دالة للجمع
function add(a, b) {
    return a + b;
}

// تعريف دالة للطرح
function subtract(a, b) {
    return a - b;
}

// تصدير الدالتين ليتم استخدامهما في ملفات أخرى
// يمكننا تصدير كائن يحتوي على عدة وظائف
module.exports = {
    addNumbers: add,
    subtractNumbers: subtract
};

ملاحظة تقنية: في Node.js، كل ملف JavaScript يعتبر وحدة (Module) بشكل افتراضي. الكائن module.exports هو الطريقة التي تحدد بها ما الذي يجب أن يكون متاحًا للاستخدام من هذه الوحدة عند استيرادها بواسطة ملفات أخرى.

الخطوة الثانية: استيراد الوحدة واستخدام وظائفها

الآن بعد أن قمنا بإنشاء وتصدير الدوال من الوحدة utils.js، سنقوم بإنشاء ملف JavaScript آخر (عادةً ما يكون الملف الرئيسي للتطبيق) لاستيراد هذه الوحدة واستخدام الدوال المصدرة منها.

// الملف: app.js

// استيراد الوحدة التي أنشأناها في الخطوة الأولى
// نستخدم دالة require() مع المسار النسبي للملف
const mathOperations = require('./utils');

// استخدام دالة الجمع المصدرة من الوحدة
const sum = mathOperations.addNumbers(10, 5);
// استخدام دالة الطرح المصدرة من الوحدة
const difference = mathOperations.subtractNumbers(10, 5);

console.log('مجموع الأرقام:', sum);
console.log('الفرق بين الأرقام:', difference);

ملاحظة تقنية: تستخدم دالة require() في Node.js لاستيراد الوحدات. عند استيراد وحدة محلية، يجب تحديد المسار النسبي للملف (مثل './utils'). ستقوم require() بإرجاع القيمة التي تم تعيينها لـ module.exports في الوحدة المستوردة.

الخطوة الثالثة: تصدير فئة (Class) أو قيمة واحدة

يمكننا أيضاً تصدير فئة كاملة أو دالة واحدة مباشرةً بدلاً من كائن يحتوي على عدة دوال. هذا مفيد عندما تكون الوحدة مخصصة لتوفير كيان واحد رئيسي.

// الملف: calculator.js

// تعريف فئة بسيطة للحسابات
class Calculator {
    constructor() {
        this.result = 0;
    }

    add(num) {
        this.result += num;
        return this; // لإتاحة التسلسل (chaining) في استدعاء الدوال
    }

    subtract(num) {
        this.result -= num;
        return this;
    }

    getResult() {
        return this.result;
    }
}

// تصدير الفئة مباشرةً بدلاً من كائن
module.exports = Calculator;

والآن، لنقم بتحديث ملف app.js لاستيراد واستخدام هذه الفئة:

// الملف: app.js (تكملة)

// استيراد فئة Calculator مباشرةً
const Calculator = require('./calculator');

// إنشاء كائن (Instance) من الفئة
const myCalc = new Calculator();

// استخدام الدوال المتسلسلة (chaining) من كائن الفئة
const finalResult = myCalc.add(20).subtract(7).getResult();

console.log('النتيجة النهائية من الآلة الحاسبة:', finalResult);

ملاحظة تقنية: عند تصدير فئة أو دالة واحدة مباشرةً باستخدام module.exports = MyClass;، يمكنك استيرادها مباشرةً بالاسم const MyClass = require('./myclass');، مما يجعل الكود أكثر وضوحاً عند التعامل مع كيانات رئيسية مفردة لكل وحدة.

الكود النهائي الكامل (للتجربة في Node.js)

للتجربة، قم بإنشاء ثلاثة ملفات في نفس المجلد: utils.js، calculator.js، و app.js، ثم انسخ الكود التالي لكل ملف:

الملف: utils.js

function add(a, b) {
    return a + b;
}

function subtract(a, b) {
    return a - b;
}

module.exports = {
    addNumbers: add,
    subtractNumbers: subtract
};

الملف: calculator.js

class Calculator {
    constructor() {
        this.result = 0;
    }

    add(num) {
        this.result += num;
        return this;
    }

    subtract(num) {
        this.result -= num;
        return this;
    }

    getResult() {
        return this.result;
    }
}

module.exports = Calculator;

الملف: app.js

// استيراد وحدة العمليات الرياضية
const mathOperations = require('./utils');
// استيراد فئة الآلة الحاسبة
const Calculator = require('./calculator');

console.log('--- استخدام الدوال المصدرة من utils.js ---');
const sum = mathOperations.addNumbers(10, 5);
const difference = mathOperations.subtractNumbers(10, 5);

console.log('مجموع الأرقام:', sum);
console.log('الفرق بين الأرقام:', difference);

console.log('\n--- استخدام فئة الآلة الحاسبة من calculator.js ---');
const myCalc = new Calculator();
const finalResult = myCalc.add(20).subtract(7).getResult();
console.log('النتيجة النهائية من الآلة الحاسبة:', finalResult);

لتشغيل الكود، افتح الطرفية (Terminal) في نفس المجلد واكتب الأمر:

node app.js

النتيجة المتوقعة

عند تشغيل ملف app.js، ستحصل على المخرجات التالية في الطرفية:

--- استخدام الدوال المصدرة من utils.js ---
مجموع الأرقام: 15
الفرق بين الأرقام: 5

--- استخدام فئة الآلة الحاسبة من calculator.js ---
النتيجة النهائية من الآلة الحاسبة: 13