Node.js / الأساسي: بيئة تشغيل Node.js / الدرس 6
الإعدادات وبرامج سطر الأوامر
حوّل الإعدادات النصية إلى قيم متحقق منها، واجعل أداة سطر الأوامر واضحة للبشر والأتمتة والاختبارات.
في هذه الصفحة
أهداف الدرس
- اشرح المفاهيم والمفاضلات المتعلقة بموضوع «الإعدادات وبرامج سطر الأوامر».
- توقع المثالين وتحقق من مخرجاتهما وسلوك تنظيف الموارد فيهما.
- شخّص الإخفاقات الثلاثة الشائعة وطبق الحلول المشروحة على مدخلات مشابهة.
الإعدادات مدخلات
متغيرات البيئة نصوص أو undefined وليست أرقاما وقِيما منطقية. النص "false" صادق منطقيا في JavaScript، لذا لا تحلل Boolean(process.env.FEATURE) علما منطقيا. تحقق من الإعدادات مرة عند البدء وأنشئ كائنا صغيرا لبقية التطبيق. ميّز القيمة الغائبة عن الفارغة عمدا. تفيد القيم الافتراضية للإعدادات الاختيارية، لكن استخدام افتراضي صامت لسر مطلوب أو عنوان قاعدة قد يوجه التطبيق إلى نظام خاطئ. يجب كشف أخطاء الإعداد قبل إعلان الجاهزية.
تحليل عقد صارم
اختر الصياغة والمدى المسموحين لكل حقل. للمنفذ، تكون الأرقام العشرية ومجال الأعداد الصحيحة أوضح من قبول أي تحويل Number. قد تقبل parseInt بادئة مدخل مشوه مثل "12oops"، وهذا غير مناسب غالبا للإعدادات. يسمح المثال الأول بالمنفذ صفر عمدا للاختبارات المحلية؛ وقد يختلف عقد الاستماع المنشور. يقبل العلم true أو false فقط. يحد تجميد الكائن السطحي من تعديله عرضا، لكن القيم المتداخلة تحتاج إلى معالجة مستقلة.
استقلال دالة التحليل
يمرر المثال كائنا عاديا بدلا من تعديل بيئة العملية. يجعل ذلك الحالات ثابتة ويمنع تداخل الاختبارات، ويسمح لبدء التطبيق باستدعاء الدالة نفسها مع process.env. لا توزع قراءة البيئة على الوحدات كلها، لأن ذلك يخفي الاعتماديات ويصعّب تدقيق التغييرات. يختلف تحميل ملفات البيئة بحسب الإصدار وأمر البدء؛ لذا وثّق مصدر الإعدادات وأولوياتها، وأبعد الأسرار عن المستودع ومخرجات الأمثلة واستجابات الأخطاء والسجلات التشخيصية.
function config(env) {
const text = env.PORT ?? '0';
if (!/^\d+$/.test(text)) throw new Error('Invalid PORT');
const port = Number(text);
if (!Number.isInteger(port) || port > 65535) throw new Error('Invalid PORT');
const flag = env.FEATURE ?? 'false';
if (!['true', 'false'].includes(flag)) throw new Error('Invalid FEATURE');
return Object.freeze({ port, feature: flag === 'true' });
}
console.log(JSON.stringify(config({ PORT: '3000', FEATURE: 'false' })));
try { config({ PORT: '12oops' }); } catch (error) { console.log(error.message); }
{"port":3000,"feature":false}
Invalid PORT
تبقى الراية false، ويرفض النص العددي المشوه بدلا من تحليل بادئته فقط.
لأداة سطر الأوامر قناتا إخراج
تتلقى الأداة المعاملات عبر process.argv، ويشغل الملف التنفيذي ومسار السكربت أول عنصرين. ضع النتائج العادية القابلة للمعالجة على stdout، والتشخيص على stderr. تخبر حالة الخروج غير الصفرية الأتمتة بالفشل. يعزل المثال الثاني تفسير المعاملات في دالة كي يعرض الحالتين دون إنهاء الدرس بفشل متعمد. في نقطة الدخول الفعلية التقط خطأ التحقق واطبع تشخيصا موجزا على stderr واضبط process.exitCode إلى واحد بعد التنظيف.
function run(args) {
if (args.length !== 1 || !/^\d+$/.test(args[0])) throw new Error('Usage: double <integer>');
const value = Number(args[0]);
if (!Number.isSafeInteger(value) || !Number.isSafeInteger(value * 2)) throw new Error('Integer out of range');
return String(value * 2);
}
console.log(run(['8']));
try { run(['eight']); } catch (error) { console.log(error.message); }
16
Usage: double <integer>
تقبل دالة المعاملات عددا صحيحا آمنا غير سالب واحدا. تستدعيها نقطة الدخول الحقيقية مع process.argv.slice(2).
تصميم حدود آمنة للأتمتة
المعاملات ومتغيرات البيئة مدخلات غير موثوقة حتى عندما تمررها الطرفية. تجنب تركيب أوامر shell منها؛ واستخدم واجهات مباشرة أو ملفا تنفيذيا مع مصفوفة معاملات منفصلة عند الحاجة إلى إنشاء عملية. لا تسجل البيئة كاملة لتشخيص إعداد مفقود؛ بل اذكر الاسم والصيغة المطلوبة. أضف وضع مساعدة يشرح المعاملات، واجعل تكرار التشغيل آمنا قدر الإمكان، ووثّق الكتابة إلى الملفات. تجعل هذه الحدود الأداة جزءا موثوقا من سير عمل أكبر.
الأخطاء الشائعة وإصلاحها
يفعّل النص false ميزة
- لماذا يحدث؟
- اختبر التحويل وجود النص بدلا من مضمونه.
- كيف تصلحه؟
- اقبل قائمة قيم صريحة وقارن بـ "true".
- كيف تتجنب تكراره؟
- اختبر الغياب والفراغ وtrue وfalse والقيم غير الصالحة.
تنجح الأداة بعد طباعة خطأ
- لماذا يحدث؟
- لم تضبط حالة خروج تدل على الفشل.
- كيف تصلحه؟
- اضبط process.exitCode بعد المعالجة والتنظيف.
- كيف تتجنب تكراره؟
- اختبر الحالة والمخرجات معا.
يكشف سجل الخطأ سرا
- لماذا يحدث؟
- سُجلت البيئة أو الإعدادات كاملة.
- كيف تصلحه؟
- احذف القيم الحساسة وغيّر أي اعتماد كُشف.
- كيف تتجنب تكراره؟
- استخدم قائمة سماح لحقول التشخيص الآمنة.
اختبر فهمك
1. يغيب الإعداد المطلوب API_KEY. هل يستخدم البدء نصا فارغا؟
اعرض الحل المشروح
لا. تحقق من الوجود والصيغة المطلوبة ثم أوقف البدء برسالة تسمي API_KEY دون طباعة قيمته. تبقى الجاهزية سلبية. يؤخر الافتراضي الفارغ الفشل إلى طلب لاحق ويصعّب التشخيص.
2. حدد stdout وstderr وحالة الخروج لمضاعفة 8 ولمدخل غير صالح.
اعرض الحل المشروح
للعدد 8 اكتب 16 على stdout واترك stderr فارغا واخرج بصفر. للمدخل غير الصالح اترك stdout فارغا واكتب التعليمات على stderr واخرج بواحد. يتيح فصل القناتين للأنبوب استهلاك البيانات الناجحة واكتشاف الفشل بوضوح.
أهم ما تعلمته
- متغيرات البيئة نصوص أو undefined وليست أرقاما وقِيما منطقية.
- اختر الصياغة والمدى المسموحين لكل حقل.
- المعاملات ومتغيرات البيئة مدخلات غير موثوقة حتى عندما تمررها الطرفية.