العربية

اكتشف الفروق بين CommonJS ووحدات ES، وهما نظاما الوحدات السائدان في JavaScript، مع أمثلة عملية ورؤى لتطوير الويب الحديث.

أنظمة الوحدات: CommonJS مقابل وحدات ES - دليل شامل

في عالم تطوير JavaScript دائم التطور، تعد الوحداتية حجر الزاوية لبناء تطبيقات قابلة للتطوير والصيانة. لقد هيمن نظاما وحدات تاريخيًا على الساحة: CommonJS ووحدات ES (ESM). يعد فهم الاختلافات والمزايا والعيوب بينهما أمرًا بالغ الأهمية لأي مطور JavaScript، سواء كان يعمل على الواجهة الأمامية باستخدام أطر عمل مثل React أو Vue أو Angular، أو على الواجهة الخلفية باستخدام Node.js.

ما هي أنظمة الوحدات؟

يوفر نظام الوحدات طريقة لتنظيم الكود في وحدات قابلة لإعادة الاستخدام تسمى الوحدات النمطية. تغلف كل وحدة قطعة معينة من الوظائف وتكشف فقط عن الأجزاء التي تحتاجها الوحدات الأخرى لاستخدامها. يعزز هذا النهج إعادة استخدام الكود، ويقلل من التعقيد، ويحسن قابلية الصيانة. فكر في الوحدات مثل لبنات البناء؛ كل لبنة لها غرض محدد، ويمكنك دمجها لإنشاء هياكل أكبر وأكثر تعقيدًا.

فوائد استخدام أنظمة الوحدات:

CommonJS: معيار Node.js

ظهر CommonJS كنظام الوحدات القياسي لـ Node.js، بيئة تشغيل JavaScript الشهيرة لتطوير جانب الخادم. تم تصميمه لمعالجة نقص نظام الوحدات المدمج في JavaScript عند إنشاء Node.js لأول مرة. تبنى Node.js نظام CommonJS كطريقته لتنظيم الكود. كان لهذا الاختيار تأثير عميق على كيفية بناء تطبيقات JavaScript على جانب الخادم.

الميزات الرئيسية لـ CommonJS:

صيغة CommonJS:

إليك مثال على كيفية استخدام CommonJS:

وحدة (math.js):

// math.js
function add(a, b) {
 return a + b;
}

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

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

الاستخدام (app.js):

// app.js
const math = require('./math');

console.log(math.add(5, 3)); // Output: 8
console.log(math.subtract(10, 4)); // Output: 6

مزايا CommonJS:

عيوب CommonJS:

وحدات ES (ESM): نظام وحدات JavaScript الموحد

وحدات ES (ESM) هي نظام الوحدات القياسي الرسمي لـ JavaScript، والذي تم تقديمه مع ECMAScript 2015 (ES6). تهدف إلى توفير طريقة متسقة وفعالة لتنظيم الكود في كل من Node.js والمتصفح. تجلب ESM دعم الوحدات الأصلي إلى لغة JavaScript نفسها، مما يلغي الحاجة إلى مكتبات خارجية أو أدوات بناء للتعامل مع الوحداتية.

الميزات الرئيسية لوحدات ES:

صيغة وحدات ES:

إليك مثال على كيفية استخدام وحدات ES:

وحدة (math.js):

// math.js
export function add(a, b) {
 return a + b;
}

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

// Or, alternatively:
// function add(a, b) {
//  return a + b;
// }
// function subtract(a, b) {
//  return a - b;
// }
// export { add, subtract };

الاستخدام (app.js):

// app.js
import { add, subtract } from './math.js';

console.log(add(5, 3)); // Output: 8
console.log(subtract(10, 4)); // Output: 6

التصديرات المسماة مقابل التصديرات الافتراضية:

تدعم وحدات ES كلاً من التصديرات المسماة والافتراضية. تسمح لك التصديرات المسماة بتصدير قيم متعددة من وحدة بأسماء محددة. تسمح لك التصديرات الافتراضية بتصدير قيمة واحدة كتصدير افتراضي للوحدة.

مثال على التصدير المسمى (utils.js):

// utils.js
export function formatCurrency(amount, currencyCode) {
 // Format the amount according to the currency code
 // Example: formatCurrency(1234.56, 'USD') might return '$1,234.56'
 // Implementation depends on desired formatting and available libraries
 return new Intl.NumberFormat('en-US', { style: 'currency', currency: currencyCode }).format(amount);
}

export function formatDate(date, locale) {
 // Format the date according to the locale
 // Example: formatDate(new Date(), 'fr-CA') might return '2024-01-01'
 return new Intl.DateTimeFormat(locale).format(date);
}
// app.js
import { formatCurrency, formatDate } from './utils.js';

const price = formatCurrency(19.99, 'EUR'); // Europe
const today = formatDate(new Date(), 'ja-JP'); // Japan

console.log(price); // Output: €19.99
console.log(today); // Output: (varies based on date)

مثال على التصدير الافتراضي (api.js):

// api.js
const api = {
 fetchData: async (url) => {
 const response = await fetch(url);
 return response.json();
 }
};

export default api;
// app.js
import api from './api.js';

api.fetchData('https://example.com/data')
 .then(data => console.log(data));

مزايا وحدات ES:

عيوب وحدات ES:

CommonJS مقابل وحدات ES: مقارنة تفصيلية

إليك جدول يلخص الفروق الرئيسية بين CommonJS ووحدات ES:

الميزة CommonJS وحدات ES
صيغة الاستيراد require() import
صيغة التصدير module.exports export
التحميل متزامن غير متزامن (في المتصفحات)، متزامن/غير متزامن في Node.js
التحليل الثابت لا نعم
دعم المتصفح الأصلي لا نعم
حالة الاستخدام الأساسية Node.js (تاريخيًا) المتصفحات و Node.js (حديثًا)

أمثلة عملية وحالات استخدام

مثال 1: إنشاء وحدة أدوات قابلة لإعادة الاستخدام (التدويل)

لنفترض أنك تبني تطبيق ويب يحتاج إلى دعم لغات متعددة. يمكنك إنشاء وحدة أدوات قابلة لإعادة الاستخدام للتعامل مع التدويل (i18n).

وحدات ES (i18n.js):

// i18n.js
const translations = {
 'en': {
 'greeting': 'Hello, world!'
 },
 'fr': {
 'greeting': 'Bonjour, le monde !'
 },
 'es': {
 'greeting': '¡Hola, mundo!'
 }
};

export function getTranslation(key, language) {
 return translations[language][key] || key;
}
// app.js
import { getTranslation } from './i18n.js';

const language = 'fr'; // Example: User selected French
const greeting = getTranslation('greeting', language);
console.log(greeting); // Output: Bonjour, le monde !

مثال 2: بناء عميل API معياري (REST API)

عند التفاعل مع واجهة برمجة تطبيقات REST، يمكنك إنشاء عميل API معياري لتغليف منطق واجهة برمجة التطبيقات.

وحدات ES (apiClient.js):

// apiClient.js
const API_BASE_URL = 'https://api.example.com';

async function get(endpoint) {
 const response = await fetch(`${API_BASE_URL}${endpoint}`);
 if (!response.ok) {
 throw new Error(`HTTP error! status: ${response.status}`);
 }
 return response.json();
}

async function post(endpoint, data) {
 const response = await fetch(`${API_BASE_URL}${endpoint}`, {
 method: 'POST',
 headers: {
 'Content-Type': 'application/json'
 },
 body: JSON.stringify(data)
 });
 if (!response.ok) {
 throw new Error(`HTTP error! status: ${response.status}`);
 }
 return response.json();
}

export { get, post };
// app.js
import { get, post } from './apiClient.js';

get('/users')
 .then(users => console.log(users))
 .catch(error => console.error('Error fetching users:', error));

post('/users', { name: 'John Doe', email: 'john.doe@example.com' })
 .then(newUser => console.log('New user created:', newUser))
 .catch(error => console.error('Error creating user:', error));

الترحيل من CommonJS إلى وحدات ES

يمكن أن يكون الترحيل من CommonJS إلى وحدات ES عملية معقدة، خاصة في قواعد الكود الكبيرة. إليك بعض الاستراتيجيات التي يجب مراعاتها:

Node.js ووحدات ES:

لقد تطور Node.js لدعم وحدات ES بشكل كامل. يمكنك استخدام وحدات ES في Node.js عن طريق:

اختيار نظام الوحدات المناسب

يعتمد الاختيار بين CommonJS ووحدات ES على احتياجاتك الخاصة والبيئة التي تقوم بالتطوير فيها:

الخاتمة

يعد فهم الاختلافات بين CommonJS ووحدات ES أمرًا ضروريًا لأي مطور JavaScript. بينما كان CommonJS تاريخيًا هو المعيار لـ Node.js، أصبحت وحدات ES بسرعة الخيار المفضل لكل من المتصفحات و Node.js نظرًا لطبيعتها الموحدة وفوائد الأداء ودعم التحليل الثابت. من خلال التفكير بعناية في احتياجات مشروعك والبيئة التي تقوم بالتطوير فيها، يمكنك اختيار نظام الوحدات الذي يناسب متطلباتك بشكل أفضل وبناء تطبيقات JavaScript قابلة للتطوير والصيانة وفعالة.

مع استمرار تطور نظام JavaScript البيئي، يعد البقاء على اطلاع بأحدث اتجاهات أنظمة الوحدات وأفضل الممارسات أمرًا بالغ الأهمية للنجاح. استمر في التجربة مع كل من CommonJS ووحدات ES، واستكشف الأدوات والتقنيات المختلفة المتاحة لمساعدتك في بناء كود JavaScript معياري وقابل للصيانة.