دليل شامل: تصحيح أخطاء تطبيقات Node.js باستخدام VSCode و Docker والطرفية
مقدمة في عالم تصحيح الأخطاء
في عالم تطوير البرمجيات، يُعد العثور على الأخطاء وإصلاحها جزءًا لا يتجزأ من العملية اليومية. غالبًا ما يقضي المطورون وقتًا طويلاً في محاولة فهم سلوك تطبيقاتهم وتحديد المشكلات بدقة. في هذا المقال، سنتعمق في مجموعة من الأدوات القوية التي تساعدك على اكتشاف الأخطاء وإصلاحها بفعالية في تطبيقات Node.js، وذلك باستخدام بيئة التطوير المرئية VSCode، ومنصة الحاويات Docker، والطرفية (Terminal) الخاصة بك. سنتعلم أيضًا (ونطبق عمليًا) ست طرق مختلفة لتصحيح أخطاء تطبيقات Node.js.
هل يمكنك تخمين الطرق الست الممكنة لتصحيح أخطاء تطبيق Node.js؟ يُعد فهم ما يدور في تطبيقاتك وتحديد الأخطاء بسرعة من الممارسات الأساسية في حياة كل مطور. بينما ستستخدم معظم الأمثلة المعروضة هنا Node.js، يمكنك تطبيق هذه الأساليب أيضًا على تطبيقات الواجهة الأمامية (front-end) المكتوبة بلغة JavaScript. على الرغم من إمكانية استخدام محررات أو بيئات تطوير متكاملة (IDEs) أخرى مثل Visual Studio أو WebStorm، إلا أننا سنركز في هذا الدليل على VSCode نظرًا لشعبيته ومرونته. يمكنك بسهولة تكييف ما تتعلمه هنا ليناسب محرر الأكواد الذي تفضله.
بحلول نهاية هذا المقال، ستكون قد أتقنت كيفية فحص تطبيقاتك باستخدام الأدوات والأساليب التالية:
Node.js Read-Eval-Print-Loop (REPL)- متصفحات الويب (
Browser) DockerVSCodeوالبيئة المحلية (Local environment)VSCodeوDockerVSCodeوالبيئة البعيدة (Remote environment)
المتطلبات الأساسية
في الخطوات التالية، سنقوم بإنشاء واجهة برمجة تطبيقات ويب (Web API) باستخدام Node.js وتصحيح أخطائها باستخدام VSCode و Docker. قبل البدء في كتابة الكود، تأكد من تثبيت الأدوات التالية على جهازك:
DockerNode.js v14أو أحدثVSCode
فهم طبيعة الأخطاء الشائعة
إذا كنت تعمل كمطور لبعض الوقت، فربما تدرك أن الواقع يختلف عن الأفلام. في الحقيقة، يجب أن يقضي المطورون 80% من وقت عملهم في التفكير و 20% فقط في كتابة الكود. لكن في الواقع، يتم قضاء معظم تلك الـ 80% في حل المشكلات، وإصلاح الأخطاء، ومحاولة فهم كيفية تجنب المزيد من المشاكل. قد تبدو ليالي الجمعة كما هو موضح في الصورة المتحركة أدناه:

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

هل هذا السلوك المفترض أن يعمل مع التنفيذ الحالي؟
قد يكون الأمر يتعلق بعبارة شرطية (if statement) لم تقيّم شروطي بشكل صحيح، أو حتى حلقة تكرارية (loop) كان يجب أن تتوقف بعد عدد معين من التفاعلات ولكنها لم تفعل. ما الذي يحدث هنا؟
ما الذي يحدث هنا؟
في هذه الحالة، قد يكون خطأ داخليًا أو شيئًا لم أره من قبل. لذلك أبحث عنه في Google لمعرفة ما حدث في تطبيقي. على سبيل المثال، توضح الصورة أدناه خطأ داخليًا في تدفق Node.js (stream error) لا يوضح ما فعلته خطأ في برنامجي.

أساليب تصحيح الأخطاء في اللغات النصية
عادةً، لا يحتاج المطورون الذين يستخدمون لغات نصية (scripting languages) مثل Ruby أو Python أو JavaScript إلى استخدام بيئات تطوير متكاملة (IDEs) مثل Visual Studio و WebStorm وما إلى ذلك. بدلاً من ذلك، غالبًا ما يختارون استخدام محررات خفيفة الوزن مثل Sublime Text و VSCode و VIM وغيرها. توضح الصورة أدناه ممارسة شائعة لفحص التطبيقات و”تصحيح أخطائها”. يقومون بطباعة عبارات للتحقق من حالات التطبيق وقيمه.

الشروع في العمل: إعداد المشروع التجريبي
الممارسة التي نظرنا إليها في القسم السابق ليست منتجة بالقدر الكافي. يمكننا الخلط بين أسماء النصوص والقيم، وطباعة متغيرات غير صحيحة، وإضاعة الوقت في أخطاء بسيطة أو أخطاء إملائية. في الأقسام التالية، سأوضح لك طرقًا أخرى لتحسين بحثك عن الأخطاء والتحقق من العبارات. الهدف الرئيسي هنا هو إظهار مدى سهولة تصحيح أخطاء التطبيق. باستخدام الأدوات الأكثر شيوعًا، ستتمكن من فحص الكود بدءًا من أوامر الطرفية البسيطة وصولاً إلى الأجهزة البعيدة من جميع أنحاء العالم.
إنشاء المشروع التجريبي
قبل أن نتعمق في مفاهيم تصحيح الأخطاء، يجب عليك إنشاء تطبيق لفحصه. لذا، أولاً، قم بإنشاء واجهة برمجة تطبيقات ويب (Web API) باستخدام وحدة HTTP الأصلية في Node.js. يجب أن تحصل الواجهة على جميع الحقول من الطلب، وتجمع جميع القيم منها، ثم تستجيب للمُرسِل بالنتائج المحسوبة. اختر مجلدًا فارغًا على جهازك ولنبدأ بواجهة برمجة تطبيقات الويب.
أولاً، قم بإنشاء ملف Math.js الذي سيكون مسؤولاً عن جمع جميع الحقول من كائن JavaScript:
//Math.js module .exports = { sum(...args) { return args.reduce( ( prev, next ) => Number (prev) + Number (next), 0 ) } }
ثانيًا، قم بإنشاء ملف خادم Node.js باستخدام الكود أدناه. انسخ القيمة وأنشئ ملفك ثم الصقها هناك. سأشرح ما يحدث هناك لاحقًا. لاحظ أن هذه الواجهة هي واجهة برمجة تطبيقات مدفوعة بالأحداث (event-driven API) وستتعامل مع الطلبات باستخدام نهج تدفقات Node.js (Node.js Streams).
//server.js const Http = require ( 'http' ) const PORT = 3000 const { promisify } = require ( 'util' ) const { pipeline } = require ( 'stream' ) const pipelineAsync = promisify(pipeline) const { sum } = require ( './Math' ) let counter = 0 Http.createServer( async (req, res) => { try { await pipelineAsync( req, async function * ( source ) { source.setEncoding( 'utf8' ) for await ( const body of source) { console .log( `[ ${++counter} ] - request!` , body) const item = JSON .parse(body) const result = sum(...Object.values(item)) yield `Result: ${result} ` } }, res ) } catch (error) { console .log( 'Error!!' , error) } }) .listen(PORT, () => console .log( 'server running at' , PORT))
حسنًا، قد يبدو هذا الكود غير عادي لواجهة برمجة تطبيقات ويب بسيطة. دعني أشرح ما يحدث. كبديل، تعتمد هذه الواجهة على تدفقات Node.js (Node.js Streams). لذا ستقوم بقراءة البيانات عند الطلب من الطلبات الواردة، ومعالجتها، والاستجابة لها باستخدام كائن الاستجابة (response object). في السطر (11) توجد دالة pipeline التي ستدير تدفق الأحداث. إذا حدث خطأ ما في أي دالة تدفق، فستقوم بإلقاء استثناء وسنتعامل مع الأخطاء في عبارة catch من try/catch. في السطر (6) نقوم باستيراد دالة sum من وحدة Math ثم معالجة البيانات الواردة في السطر (19). لاحظ أنه في السطر (19) توجد دالة Object.values التي ستنشر جميع قيم الكائن وتعيدها كمصفوفة. على سبيل المثال، سيتم تحليل كائن {v1: 10, v2: 20} إلى [10, 20].
تشغيل التطبيق
إذا كان لديك نظام يعتمد على Unix، يمكنك استخدام أمر cURL، وهو أمر أصلي لإجراء طلبات الويب. إذا كنت تعمل على نظام التشغيل Windows، يمكنك استخدام Windows Subsystem for Linux أو Git bash لتنفيذ تعليمات Unix.
أنشئ ملف run.sh بالكود التالي. ستقوم بإنشاء كود لطلب واجهة برمجة التطبيقات الخاصة بك. إذا كنت معتادًا على Postman، يمكنك تخطي هذا الملف والتنفيذ من هناك.
curl -i \ -X POST \ -d '{"valor1": "120", "valor2": "10"}' \ http://localhost:3000
لاحظ أنك تحتاج إلى تثبيت Node.js الإصدار 14 أو أعلى. ستحتاج إلى فتح جلستين طرفيتين (terminal sessions). في بيئتي، قمت بتقسيم طرفيتين في مثيل VSCode الخاص بي. على اليسار، قم بتشغيل node server.js وعلى اليمين قم بتشغيل bash run.sh كما يلي:

تصحيح الأخطاء باستخدام Node.js REPL (Read-Eval-Print-Loop)
يمكن لـ Node.js أن تساعدك في إنشاء أفضل تطبيق ممكن. REPL هي آلية لتصحيح الأخطاء وفحص تطبيقات Node.js من الطرفية. عندما تضيف العلامة inspect بعد أمر node، سيتوقف البرنامج مباشرة عند السطر الأول من الكود كما هو موضح أدناه:

أولاً، ستكتب الكلمة المفتاحية debugger مباشرة بعد console.log الخاص بالمتغير counter في السطر (17) ثم تقوم بتنفيذ node inspect server.js مرة أخرى. لاحظ أنه يمكنك التفاعل مع واجهة برمجة تطبيقات REPL باستخدام الأوامر المدرجة في الوثائق الرسمية. في الصورة التالية، سترى مثالاً عمليًا لكيفية عمل REPL باستخدام بعض الأوامر التالية:
list(100): يعرض أول 100 سطر من الكود.setBreakpoint(17): يضع نقطة توقف (breakpoint) في السطر 17.clearBreakpoint(17): يزيل نقطة توقف في السطر 17.exec body: يقيم المتغيرbodyويطبع نتيجته.cont: يواصل تنفيذ البرنامج.
توضح الصورة أدناه كيف يعمل ذلك عمليًا:

أوصي بشدة بتجربة استخدام عبارة watch. كما هو الحال في المتصفح، يمكنك مراقبة العبارات عند الطلب. في جلسة REPL الخاصة بك، اكتب watch(counter) ثم cont. لاختبار المراقبة، تحتاج إلى اختيار نقطة توقف – استخدم setBreakpoint(line) لذلك. عندما تقوم بتشغيل run.sh، سيتوقف البرنامج عند نقطة التوقف الخاصة بك ويعرض المراقبين (watchers). قد ترى النتيجة التالية في الطرفية الخاصة بك:

تصحيح الأخطاء عبر متصفحات Chromium
يُعد تصحيح الأخطاء في المتصفح أكثر شيوعًا من تصحيحها من خلال جلسات الطرفية. بدلاً من إيقاف الكود في السطر الأول، سيواصل البرنامج تنفيذه مباشرة قبل تهيئته. قم بتشغيل node --inspect server.js ثم انتقل إلى المتصفح. افتح قائمة أدوات المطور (DevTools) (بالضغط على F12 في معظم المتصفحات). ثم ستظهر أيقونة Node.js. انقر عليها. بعد ذلك، في قسم المصادر (Sources)، يمكنك تحديد الملف الذي تريد تصحيح أخطائه كما هو موضح في الصورة أدناه:

تجربة تصحيح الأخطاء المتكاملة في VSCode
التبديل ذهابًا وإيابًا إلى المتصفح ليس ممتعًا حقًا طالما أنك تكتب الكود في محرر. أفضل تجربة هي تشغيل الكود وتصحيح أخطائه في نفس المكان. لكن هذا ليس سحرًا. أنت تقوم بتهيئة وتحديد الملف الرئيسي. دعنا نقوم بتهيئته باتباع الخطوات أدناه:
ستحتاج إلى فتح ملف launch.json. يمكنك فتحه بالضغط على Ctrl + Shift + P أو Command + Shift + P على نظام macOS، ثم كتابة launch. اختر الخيار Debug: Open launch.json. بالإضافة إلى ذلك، يمكنك الضغط على F5 وقد يفتح الملف أيضًا. في الخطوة التالية من المعالج، انقر على خيار Node.js. ربما رأيت ملف JSON في المحرر مع التكوين المسبق لتصحيح الأخطاء. املأ حقل program باسم ملفك – هذا يخبر VSCode ما هو الملف الرئيسي. لاحظ أن هناك رمز ${workspaceFolder}. لقد كتبته لتحديد أن الملف موجود في المجلد الحالي الذي أعمل عليه:
{ "version" : "0.2.0" , "configurations" : [ { "type" : "node" , "request" : "launch" , "name" : "Launch Program" , "skipFiles" : [ "<node_internals>/**" ], "program" : "${workspaceFolder}/server.js" } ] }
لقد أوشكنا على الانتهاء! انتقل إلى الكود المصدري في ملف server.js وقم بتعيين نقطة توقف في السطر 16 بالنقر على الجانب الأيسر من مؤشر سطر الكود. قم بتشغيله بالضغط على F5 وقم بتشغيل server.js باستخدام run.sh، والذي سيعرض الإخراج التالي:

تصحيح أخطاء التطبيقات المعتمدة على Docker
أنا شخصيًا أحب استخدام Docker. فهو يساعدنا على البقاء قريبين قدر الإمكان من بيئة الإنتاج مع عزل التبعيات في ملف وصفة (receipt file). إذا كنت ترغب في استخدام Docker، فأنت بحاجة إلى تهيئته في ملف تكوين Docker. انسخ الكود أدناه، وأنشئ ملفًا جديدًا بجانب server.js والصقه فيه.
FROM node: 14 -alpine ADD . . CMD node --inspect=0.0.0.0 server.js
أولاً، ستحتاج إلى تنفيذ أمر بناء Docker (Docker build) في مجلدك لبناء التطبيق عن طريق تشغيل docker build -t app .. ثانيًا، ستحتاج إلى كشف منفذ التصحيح (9229) ومنفذ الخادم (3000) حتى يتمكن المتصفح أو VSCode من مراقبتهما وإرفاق عبارة تصحيح الأخطاء.
docker run \ -p 3000:3000 \ -p 9229:9229 \ app
إذا قمت بتشغيل ملف run.sh مرة أخرى، فيجب أن يطلب الخادم الذي يعمل على Docker. تصحيح أخطاء تطبيقات Docker على VSCode ليس مهمة صعبة. تحتاج إلى تغيير التكوين لإرفاق مصحح أخطاء على جذر بعيد (remote root). استبدل ملف launch.json الخاص بك بالكود أدناه:
{ "configurations" : [ { "type" : "node" , "request" : "attach" , "name" : "Docker: Attach to Node" , "remoteRoot" : "${workspaceFolder}" , "localRoot" : "${workspaceFolder}" } ] }
طالما أن تطبيقك يعمل على Docker ويكشف منفذ التصحيح الافتراضي (9229)، فإن التكوين أعلاه سيربط التطبيق بالدليل الحالي. تشغيل F5 وتشغيل التطبيق سيؤدي إلى نفس النتيجة كما لو كان يعمل محليًا.
تصحيح الأخطاء عن بُعد باستخدام VSCode
تصحيح الأخطاء عن بُعد أمر مثير! يجب أن تضع في اعتبارك بعض المفاهيم قبل البدء في كتابة الكود:
- ما هو عنوان
IP Addressللهدف؟ - كيف تم إعداد دليل العمل البعيد (
remote working directory)؟
سأقوم بتغيير ملف launch.json الخاص بي وإضافة العنوان البعيد. لدي جهاز كمبيوتر آخر في المنزل متصل بنفس الشبكة. عنوان IP الخاص به هو 192.168.15.12. أيضًا، لدي دليل عمل جهاز Windows هنا: c://Users/Ana/Desktop/remote-vscode/. يعتمد نظام macOS على أنظمة Unix لذا فإن بنية المجلد تختلف عن جهاز Windows الخاص بي. يجب أن يتغير تعيين بنية الدليل إلى /Users/Ana/Desktop/remote-vscode/.
{ "version" : "0.2.0" , "configurations" : [ { "type" : "node" , "request" : "attach" , "name" : "Attach to Remote" , "address" : "192.168.15.12" , "port" : 9229 , "localRoot" : "${workspaceFolder}" , "remoteRoot" : "/Users/Ana/Desktop/remote-vscode/" , "trace" : true , "sourceMaps" : true , "skipFiles" : [ "<node_internals>/**" ] } ] }
في هذه الحالة بالذات، ستحتاج إلى جهازين مختلفين على الأقل لاختبار ذلك. يتيح لك هذا الإعداد تصحيح الأخطاء في تطبيق يعمل على جهاز آخر، مما يفتح آفاقًا جديدة لإدارة المشاريع المعقدة والبيئات الموزعة.
نصائح أخيرة لتحسين إنتاجيتك
توقف عن استخدام console.log لتصحيح الأخطاء! نصيحتي لك اليوم هي أن تكون كسولًا تجاه المهام اليدوية المتكررة. تعلم اختصارًا أو أداة جديدة كل يوم لتحسين إنتاجيتك. تعلم المزيد عن الأدوات التي تعمل عليها يوميًا وسيساعدك ذلك على قضاء المزيد من الوقت في التفكير بدلاً من كتابة الكود. في هذا المقال، رأيت كيف يمكن أن يكون VSCode أداة مفيدة لتصحيح أخطاء التطبيقات. وكان VSCode مجرد مثال. استخدم ما هو أكثر راحة لك. إذا اتبعت هذه النصائح، فإن السماء هي حدود إمكانياتك.
الخلاصة التقنية
لقد استعرضنا في هذا الدليل مجموعة متنوعة من الأساليب والأدوات المتقدمة لتصحيح أخطاء تطبيقات Node.js، بدءًا من استخدام REPL في الطرفية، مرورًا بمتصفحات Chromium، وصولًا إلى التكامل القوي الذي يقدمه VSCode مع البيئات المحلية، وحاويات Docker، وحتى التصحيح عن بُعد. هذه الأدوات لا تقتصر على مجرد تحديد الأخطاء، بل تمكن المطورين من فهم أعمق لسلوك تطبيقاتهم، وتدفق البيانات، وحالة المتغيرات في نقاط زمنية حرجة. الانتقال من الاعتماد المفرط على console.log إلى استخدام مصححات الأخطاء الاحترافية يمثل قفزة نوعية في إنتاجية المطورين وجودة الكود. إن إتقان هذه التقنيات يقلل بشكل كبير من الوقت المستغرق في حل المشكلات، ويساهم في بناء تطبيقات أكثر استقرارًا وموثوقية.
شكرًا لك على قراءتك. أقدر حقًا الوقت الذي قضيناه معًا. آمل أن يكون هذا المحتوى أكثر من مجرد نص. آمل أن يكون قد جعلك مفكرًا أفضل ومبرمجًا أفضل أيضًا.