0.1ما هي Node.js؟
الأساسي في 30 ثانية
- Node.js = لغة JavaScript خارج المتصفح : نفس لغة الواجهات الأمامية، عبر محرك V8، للخوادم (Servers) وواجهات API والأدوات.
- نموذج لا متزامن غير حاجب : عملية بطيئة لا توقف البرنامج — بل يُسجِّل Node دالة رد (Callback) ويواصل.
- خيط واحد لكن آلاف الاتصالات : حلقة الأحداث (Event Loop) تستدعي كل دالة عندما تصل نتيجتها.
حالة مستمرة — ساليم يحدّد موقع أول أداة خادم له
ساليم، مطوّر مبتدئ في الجزائر، لا يعرف سوى JavaScript المتصفح. يطلب منه مسؤوله خادمًا (Server) صغيرًا يردّ على طلبات صفحة ويب. يكتشف ساليم أن Node.js تُشغِّل JavaScript على الخادم بفضل محرك V8، وأن قراءة ملف لا تحجب البرنامج، وأن حلقة الأحداث (Event Loop) تُنظِّم دوال الردّ. يدوّن على بطاقة «JS في كل مكان، غير حاجب، حلقة الأحداث» ويختار اختباره الأول: عرض رسالة ثم محاكاة عملية بطيئة دون حجب.
حالة مستقلة لهذا القسم: تعود في الدرس والمخطط والنص الجاهز وتحدي 48 ساعة للقسم 0.1.
1. لغة JavaScript خارج المتصفح
Node.js هي بيئة تشغيل تُشغِّل JavaScript خارج المتصفح، خصوصًا على الخادم (Server). تجمع بين محرك V8 (محرك JavaScript السريع في Chrome) ومكتبة للوصول إلى النظام (الملفات، الشبكة). يفهم ساليم الفكرة: يحتفظ بلغته الأمامية ويستخدمها لكتابة خادم أو واجهة API أو أداة سطر أوامر. إنها «JavaScript الشاملة (Full-stack)»: لغة واحدة لكل الويب.
2. اللا تزامن غير الحاجب وحلقة الأحداث
السمة المميِّزة لـ Node هي نموذجها اللا متزامن غير الحاجب مع حلقة الأحداث (Event Loop). كثير من مهام الخادم تقوم على الانتظار: قاعدة بيانات، ملف، شبكة. فبدل الانتظار السلبي، يُسجِّل Node دالة تُستدعى لاحقًا (ردّ، Callback) عندما تجهز، وينتقل فورًا إلى شيء آخر. تدور حلقة الأحداث باستمرار: تُنفِّذ الشيفرة المتاحة وتُطلِق كل ردّ فور انتهاء عمليته. يحتفظ ساليم بالصورة: أخذ الطلب التالي بدل التسمّر في المطبخ.
3. خيط واحد، قوي في الإدخال/الإخراج، ضعيف في الحساب الثقيل
النتيجة: Node أحادية الخيط لشيفرتك لكنها تدير آلاف الاتصالات المتزامنة، لأنها لا تبقى محجوبة في الانتظار. تتفوّق في الكثيف إدخالًا/إخراجًا (I/O) (خوادم الويب، واجهات API، الزمن الحقيقي) وهي أقل ملاءمة للكثيف حسابًا (CPU) (الحسابات الطويلة التي تحتكر الخيط الوحيد). كل ما تبقّى — دوال الردّ، والوعود (Promises)، وasync/await — ينبع من هذا النموذج. دوّنها ساليم أسفل بطاقته في الجزائر: فهم حلقة الأحداث قبل كل شيء.
هل تعلم؟ الخادم الذي لا يتسكّع أبدًا
لا تنتظر أبدًا: سجِّل ردًّا وواصل.
🔎 مثال ملموس — 🔎 مثال ملموس — حاجب مقابل غير حاجب
console.log("Début");
setTimeout(() => {
console.log("Réponse de l'opération lente");
}, 100);
console.log("Fin (affichée avant la réponse)");
القراءة : يُشغِّل ساليم هذا السكربت مع Node: تظهر «Fin» قبل «Réponse»، دليل أن البرنامج لم ينتظر.
الدرس : تصل النتيجة لاحقًا عبر الردّ؛ ويبقى الخيط حرًّا في الأثناء.
مفردات القسم
- Node.js
- بيئة تشغيل تُشغِّل JavaScript خارج المتصفح (على الخادم)، مبنية على محرك V8 مع مكتبة للوصول إلى النظام.
مثال بسيط: يُشغِّل ساليم أول خادم له مكتوبًا بلغة JavaScript مع Node في الجزائر.
ما ليس كذلك: لغة مختلفة عن JavaScript المتصفح.
رد فعل: أمام حاجة خادم أو أداة، اسأل «هل يمكنني فعلها بلغة JS مع Node؟».
- محرك V8
- محرك JavaScript السريع في متصفح Chrome، يُصرِّف شيفرة JS ويُنفِّذها؛ وهو قلب Node.js.
مثال بسيط: يعرف ساليم أن JS خادمه تعمل على نفس محرك JS واجهته.
ما ليس كذلك: مكتبة شبكة أو مدير حزم.
رد فعل: احفظ V8 = سرعة التنفيذ، وNode = V8 + وصول للنظام.
- لا متزامن غير حاجب
- نموذج لا تحجب فيه العملية البطيئة البرنامج: يُسجِّل Node ردًّا ويواصل فورًا.
مثال بسيط: يُطلِق ساليم قراءة ملف ويعرض البقية دون انتظار النهاية.
ما ليس كذلك: الانتظار السلبي لنهاية عملية قبل المواصلة.
رد فعل: توقَّع دائمًا «ماذا نفعل عندما تجهز» (الردّ).
- حلقة الأحداث (Event Loop)
- الآلية المركزية التي تُنظِّم التنفيذ: تُطلِق العمليات البطيئة وتستدعي الدوال عندما تصل النتائج.
مثال بسيط: يتخيّل ساليم الحلقة التي تخدم كل ردّ فور استجابة الملف أو القاعدة.
ما ليس كذلك: خيط إضافي لكل مستخدم.
رد فعل: فكِّر «الحلقة تستدعي»، لا «البرنامج ينتظر».
- كثيف إدخال/إخراج مقابل كثيف حساب
- كثيف إدخالًا/إخراجًا (I/O): انتظارات كثيرة (خوادم، API) حيث تتفوّق Node؛ كثيف حسابًا (CPU): حسابات ثقيلة تحجب الخيط الوحيد.
مثال بسيط: يخصّص ساليم Node لواجهة API تقرأ قاعدة، ويستبعد ترميز فيديو ضخمًا.
ما ليس كذلك: اسمان لشيء واحد.
رد فعل: صنِّف كل حاجة إلى إدخال/إخراج أو حساب قبل اختيار Node.
في التطبيق — عمليًا — حدِّد موقع Node.js ونموذجها
- احفظ طبيعة Node: بيئة لتشغيل JavaScript خارج المتصفح (خوادم، API، أدوات)، بفضل محرك V8.
- حدِّد ميزة «لغة واحدة»: JavaScript للواجهة والخلفية معًا (Full-stack JS)، مثل ساليم في الجزائر.
- افهم النموذج غير الحاجب: شغِّل سكربت المثال ولاحظ أن «Fin» تصل قبل الردّ.
- حدِّد الاستخدامات الجيدة: تتألّق Node في الإدخال/الإخراج (خوادم الويب، API، الزمن الحقيقي)، وأقل في حسابات المعالج الثقيلة.
نص جاهز — اشرح Node لزميل (30 ثانية)
«Node هي JavaScript خاصتنا التي تعمل على الخادم بفضل محرك V8. عندما تقرأ ملفًا أو تستعلم قاعدة، لا تنتظر: تُسجِّل ردًّا وتعالج البقية، وتستدعي حلقة الأحداث عندما تجهز. خيط واحد يدير طلبات كثيرة، مثالي لواجهات API خاصتنا.»
يُقال مع سكربت المثال أمام العينين؛ أظهر ترتيب العرض Début ثم Fin ثم Réponse.
نموذج نسخ ولصق — لاحظ غير الحاجب
console.log("Salim lance la lecture");
setTimeout(() => {
console.log("Lecture terminée : Salim reprend ici");
}, 50);
console.log("Salim continue sans attendre");
قادم من الواجهات
تعرف JS المتصفح أصلًا: ركِّز على ما يتغيّر (لا DOM، حلقة الأحداث، الإدخال/الإخراج) وشغِّل سكربت المثال لرؤية الترتيب الحقيقي.
مبتدئ تمامًا
دون أساس JS: أعد تشغيل السكربت ثلاث مرات بتغيير المهلة (50، 200، 0) ودوّن الترتيب الثابت Début ثم البقية ثم الردّ — بديهية غير الحاجب.
ثنائي في الجزائر
يُخمِّن زميل ساليم ترتيب العرض قبل التنفيذ: من يُخطئ يشرح حلقة الأحداث على السبورة.
اختيار معماري
قبل مشروع: صنِّف الحاجة إلى إدخال/إخراج (API، خادم، زمن حقيقي ← Node مناسبة) أو حساب ثقيل (حساب ضخم ← يُرحَّل إلى خدمة أخرى).
✓ ممارسات جيدة
- فكِّر «لغة واحدة» للواجهة والخلفية (Full-stack JS).
- خصِّص Node لمهام الإدخال/الإخراج (خوادم، API، زمن حقيقي).
- افهم حلقة الأحداث قبل كل شيء.
✗ أخطاء شائعة
- الاعتقاد أن أحادي الخيط = مستخدم واحد في كل مرة.
- إطلاق حساب ثقيل على المعالج يحجب حلقة الأحداث.
- نسيان أن اللا تزامن (دوال الردّ، الوعود) ينبع من هذا النموذج.
النقاط الأساسية
- تُشغِّل Node.js لغة JavaScript خارج المتصفح (خوادم، API، أدوات CLI) عبر محرك V8 — لغة واحدة للواجهة والخلفية.
- نموذج لا متزامن غير حاجب: العمليات البطيئة لا تحجب — يُسجِّل Node ردًّا ويواصل.
- حلقة الأحداث تُنظِّم كل شيء؛ Node أحادية الخيط لكنها تدير آلاف الاتصالات المتزامنة.
- ممتازة للإدخال/الإخراج (خوادم الويب، API، الزمن الحقيقي)؛ وأقل ملاءمة لمهام الكثيف حسابًا.
تحدي 48 ساعة — طبِّق غدًا
نفِّذ السكربت غير الحاجب لساليم، وغيِّر المهلة مرتين، واشرح بصوت عالٍ لماذا تصل «Fin» قبل الردّ.
- أستطيع شرح Node.js (لغة JS خادم عبر V8) بمثال.
- نفَّذت السكربت ولاحظت الترتيب غير الحاجب.
- أعرف متى تكون Node مناسبة (إدخال/إخراج) ومتى لا تكون (حساب ثقيل).
أسئلة شائعة
Node.js أحادية الخيط: كيف تدير آلاف المستخدمين معًا؟
يجب التمييز بين «تنفيذ الشيفرة» و«انتظار عملية بطيئة». يقضي الخادم معظم وقته في الانتظار (قاعدة، ملف، شبكة). والخادم الحاجب يُكرِّس خيطه سلبيًا لذلك. أما Node غير الحاجبة فتُفوِّض العملية إلى النظام، وتُسجِّل ردًّا (Callback) وتُعيد اليد فورًا: فيعالج الخيط الطلب التالي. وتُنفِّذ حلقة الأحداث كل ردّ فور انتهاء عمليته. كما في مطعمٍ يأخذ فيه نادل جيّد الطلبات على التوالي ويقدِّم كل طبق عندما يُعلِن المطبخ جاهزيته. الحدّ: حساب ثقيل على المعالج يحتكر الخيط ويحجب كل شيء.
متى تختار Node.js، ومتى تُفضِّل تقنية أخرى؟
تتألّق Node في: التطبيقات الكثيفة إدخالًا/إخراجًا (واجهات REST، خلفيات تقرأ القواعد)، والزمن الحقيقي (دردشة، إشعارات)، وفرق Full-stack JS (لغة واحدة)، والخدمات المصغّرة والأدوات. وهي أقل ملاءمة لمهام الكثيف حسابًا (حساب علمي، معالجة صور ضخمة، تعلّم آلي) التي تحتكر الخيط الوحيد — فنُفضِّل حينها منصات أخرى أو نُرحِّل تلك الحسابات إلى خدمات متخصّصة. والاختيار الصحيح يعتمد على المشكلة (إدخال/إخراج مقابل حساب) والفريق والمنظومة.
ما الذي يُميِّز نموذج Node.js؟