المنقح Debugger في Node.js

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث

درجة الثبات: 2 - مستقر

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

سنستخدم في مثالنا هذا ملف myscript:

// myscript.js
global.x = 5;
setTimeout(() => {
 console.log('world');
}, 1000);

console.log('hello');

كما ترى، المثال المستخدم هنا بسيط، حيث يبدأ في السطر الأول بتحديد متغير عام x بقيمة 5، ثم في السطر الثاني يستخدم الدالة setTimeout‎()‎‎ في ظهور كلمة world بعد انتظار 1000 مللي ثانية (1 ثانية)، وينتهي بظهور hello في السطر الأخير (وفي هذه الحالة ستظهر على الفور قبل كلمة world التي ستتأخر لمدة ثانية). سنضع جملة debugger;‎ في النص لتفعيل نقطة توقف breakpoint في هذا الموقع من الشيفرة:

// myscript.js
global.x = 5;
setTimeout(() => {
 debugger;
 console.log('world');
}, 1000);
console.log('hello');

والآن، دعنا نشغل المنقّح، ابدأ تطبيق Node.js مع الخيار inspect ثم مسار ملف الشيفرة المُراد استخدامه، وهو في حالتنا myscript.js:

$ node inspect script_folder/myscript.js
< Debugger listening on ws://127.0.0.1:9229/2c9204a9-3569-40d3-a1e0-1e90cf2e893a
< For help see https://nodejs.org/en/docs/inspector
< Debugger attached.
Break on start in script_folder/myscript.js:1
> 1 (function (exports, require, module, __filename, __dirname) { // myscript.js
  2 global.x = 5;
  3 setTimeout(() => {
debug> cont
< hello
break in script_folder/myscript.js:4
  2 global.x = 5;
  3 setTimeout(() => {
> 4   debugger;
  5  console.log('world');
  6 }, 1000);
debug>

كما رأينا توقف المنقّح تلقائيًا في بداية تنفيذ الشيفرة، ثم أدخلنا أمر cont للاستمرار في تنفيذ الشيفرة حتى نقطة التوقف التالية، فظهرت أولًا كلمة hello وانتظر المنقّح لمدة 1 ثانية قبل التوقف عند نقطة التوقف في السطر الثالث، لأنها موضوعة بداخل دالة setTimeout()‎. بينما لو وضعنا نقطة توقف في السطر الثاني من الشيفرة:

// myscript.js
global.x = 5;
debugger;
setTimeout(() => {
 debugger;
 console.log('world');
}, 1000);
console.log('hello');

وقمنا بإعادة تنفيذ الشيفرة (بعد حفظ التعديلات) عن طريق أمر restart، ثم إدخال أمر cont للاستمرار بعد أول سطر، نجد أنه قد توقف في السطر الثاني بالفعل:

debug> restart
< Debugger listening on ws://127.0.0.1:9229/e6ccb551-d2aa-451f-81e7-0e5f09e0fb1c
< For help see https://nodejs.org/en/docs/inspector
< Debugger attached.
Break on start in script_folder/myscript.js:1
> 1 (function (exports, require, module, __filename, __dirname) { // myscript.js
  2 global.x = 5;
  3 debugger;
debug> cont
break in script_folder/myscript.js:3
  1 (function (exports, require, module, __filename, __dirname) { // myscript.js
  2 global.x = 5;
> 3 debugger;
  4 setTimeout(() => {
  5  debugger;
debug>

لندخل الأمر cont للاستمرار في تنفيذ الشيفرة حتى نقطة التوقف التالية:

debug> cont
< hello
break in script_folder/myscript.js:5
  3 debugger;
  4 setTimeout(() => {
> 5   debugger;
  6  console.log('world');
  7 }, 1000);
debug>

لتقييم واختبار الشيفرة عن بعد، يمكنك استخدام وحدة REPL عن طريق إدخال أمر repl ببساطة:

break in script_folder/myscript.js:5
  3 debugger;
  4 setTimeout(() => {
> 5   debugger;
  6  console.log('world');
  7 }, 1000);
debug> repl
Press Ctrl + C to leave debug repl
> x
5
> 4 * x
20
> y = 4
4
> y * x
20
> x = 3
3
> y * x
12

كما ترى، في وضع repl، يمكنك معرفة قيمة المتغيرات، وتحديد متغيرات جديدة، وتغيير قيمة المتغيرات، وما إلى ذلك، هذه الوحدة تمكنك من تقييم الكود بشكل تفاعلي، للعودة إلى المنقّح، اضغط Ctrl+c. أدخل next للانتقال إلى السطر التالي مباشرة. أما الضغط على زر الإدخال Enter دون كتابة أوامر يعيد تكرار آخر أمر مكتوب.

debug> next
break in script_folder/myscript.js:6
  4 setTimeout(() => {
  5  debugger;
> 6   console.log('world');
  7 }, 1000);
  8 console.log('hello');
debug>
< world
break in script_folder/myscript.js:7
  5  debugger;
  6  console.log('world');
> 7 }, 1000);
  8 console.log('hello');
  9 });
debug>

لنقم ببعض التعديلات في الشيفرة:

// myscript.js

global.x = 5;
function numbers(num) {
 x++;
 return num;
}

setTimeout(() => {
 debugger;
 console.log('world');
 console(numbers(x));
 console.log('times!');
 debugger;
}, 1000);

console.log('hello');

كما ترى، أضفنا دالة جديدة numbers مع الوسيط x، تزيد قيمة متغير x العام وتعيد قيمة num، وأضفت نقطة توقف في السطر الثاني عشر. لنعد تشغيل الشيفرة مجددًا باستخدام restart، ثم نصل إلى أول نقطة توقف باستخدام cont، ثم ندخل في وضع repl:

debug> repl
Press Ctrl + C to leave debug repl
> x
5
> numbers()
undefined
> x
6
> numbers(x)
6
> x
7
> numbers('text')
'text'
> x
8
>

كما ترى، عندما استدعينا الدالة numbers()‎ دون وسيط، فظهر خطأ. بينما عندما مررنا المتغير x كوسيط، فأعيدت قيمة المتغير، وترى أن x الآن أصبح 8 بعد استدعاء الدالة ثلاث مرات. دعنا نعود إلى وضع المنقّح مجددًا (لاحظ أنه في وضع repl يسبق المؤشر علامة ‎< فقط، بينما في وضع المنقّح يسبقه علامة ‎>debug) وذلك بالضغط على Ctrl+c كما أسلفنا سابقًا:

debug> cont
< world
< 8
< times!
break in script_folder/myscript.js:12
 10   console.log(numbers(x));
 11   console.log('times!');
>12   debugger;
 13 }, 1000);
 14 console.log('hello');
debug>

ذهبنا إلى نقطة التوقف التالية، ترى في الناتج أنه طُبِعَ الرقم 8 بدلًا من 5 أي أن التغييرات التي أجريناها في وضع repl ما زالت جارية. يمكنك أيضًا تنفيذ أي تعبير في المنقّح بسهولة باستخدام exec قبل التعبير المطلوب كما ترى تاليًا:

> 8   debugger;
  9  console.log('world');
  10   numbers(x);
debug> exec numbers(x)
5
debug> exec x
6
debug> exec x = 2
2
debug> exec numbers(x)
2
debug>

يمكنك بدء الشيفرة من جديد باستخدام أمر run، أما أمر restart يعيد فتح الشيفرة في حالة إجراء أية تعديلات على الملف:

> 1 (function (exports, require, module, __filename, __dirname) { // myscript.js
  2 global.x = 5;
  3 function numbers(num) {
debug> cont
< hello
break in script_folder/myscript.js:8
  6 }
  7 setTimeout(() => {
> 8   debugger;
  9  console.log('world');
  10  console.log(numbers(x));
debug> next
break in script_folder/myscript.js:9
  7 setTimeout(() => {
  8  debugger;
> 9   console.log('world');
  10  console.log(numbers(x));
  11  console.log('times!');
debug>

لا يقتصر تحديد نقاط التوقف من داخل الملف فقط، بل يمكنك أيضًا تحديدها من داخل المنقّح. لتحديد السطر الحالي كنقطة توقف أدخل setBreakpoint()‎ :

debug> setBreakpoint()
 4  x++;
 5  return num;
 6 }
 7 setTimeout(() => {
 8  debugger;
> 9   console.log('world');
 10   console.log(numbers(x));
 11   console.log('times!');
 12   debugger;
 13 }, 1000);
 14 console.log('hello');
debug> run
< Debugger listening on ws://127.0.0.1:9229/f2d3a89b-215d-4d9c-a5d0-3c9903ae610d
< For help see https://nodejs.org/en/docs/inspector
< Debugger attached.
Warning: script '/script_folder/myscript.js' was not loaded yet.
1 breakpoints restored.
Break on start in script_folder/myscript.js:1
> 1 (function (exports, require, module, __filename, __dirname) { // myscript.js
  2 global.x = 5;
  3 function numbers(num) {
debug> cont
< hello
break in script_folder/myscript.js:8
  6 }
  7 setTimeout(() => {
> 8   debugger;
* 9   console.log('world');
 10   console.log(numbers(x));
debug> cont
break in script_folder/myscript.js:9
  7 setTimeout(() => {
  8  debugger;
> 9   console.log('world');
 10   console.log(numbers(x));
 11   console.log('times!');

كما تلاحظ، فإن نقاط التوقف المحددة مسبقًا من المنقّح تُميّز بعلامة (*) مباشرة قبل رقم السطر. يمكنك أيضًا تحديد نقطة التوقف في سطر محدد setBreakpoint(line)‎ حيث line هنا هي رقم السطر، أو عند أول استدعاء لتعبير معين setBreakpoint('numbers()')‎. كما يمكنك إزالة نقطة التوقف باستخدام الدالة clearBreakpoint('filename', line)‎ إذ إنَّ filename هو اسم الملف و line هو رقم السطر، ففي المثال التالي نزيل نقطة التوقف في السطر التاسع من ملف myscript.js:

clearBreakpoint('myscript.js', 9)

لنتعمق قليلًا في التقدم داخل الشيفرة، أولًا أجرينا تعديلًا بسيطًا على الشيفرة وأضفنا استدعاءً لدالة numbers:

// myscript.js

global.x = 5;
function numbers(num) {
 x++;
 return num;
}

setTimeout(() => {
 debugger;
 console.log('world');
 numbers(x);
 console.log(numbers(x));
 console.log('times!');
 debugger;
}, 1000);

console.log('hello');

ثم نعيد تشغيل الشيفرة من خلال أمر restart، فالاستمرار إلى نقطة التوقف الثانية:

break in script_folder/myscript.js:8
  6 }
  7 setTimeout(() => {
> 8   debugger;
  9  console.log('world');
 10   numbers(x);
debug> next
break in script_folder/myscript.js:9
  7 setTimeout(() => {
  8  debugger;
> 9   console.log('world');
 10   numbers(x);
 11   console.log(numbers(x));
debug>
< world
break in script_folder/myscript.js:10
  8  debugger;
  9  console.log('world');
>10   numbers(x);
 11   console.log(numbers(x));
 12   console.log('times!');

ذكرنا سابقًا أنه لكي نذهب إلى السطر التالي في التنفيذ، ندخل أمر next، أما للذهاب إلى داخل الدالة التالية ندخل أمر step، فكما ترى، عندما أدخلنا next ذهبنا مباشرة إلى السطر التالي، لكن عندما أدخلنا step ذهبنا إلى داخل دالة console:

debug> next
break in script_folder/myscript.js:8
  6 }
  7 setTimeout(() => {
> 8   debugger;
  9  console.log('world');
 10   numbers(x);
debug> step
break in script_folder/myscript.js:9
  7 setTimeout(() => {
  8  debugger;
> 9   console.log('world');
 10   numbers(x);
 11   console.log(numbers(x));
debug>
break in bootstrap_node.js:316
314       enumerable: true,
315       get() {
>316         return wrappedConsole;
317       }
318     });
debug>
break in bootstrap_node.js:316
 314       enumerable: true,
 315       get() {
>316         return wrappedConsole;
 317       }
 318     });
debug>
break in script_folder/myscript.js:9
  7 setTimeout(() => {
  8  debugger;
> 9   console.log('world');
 10   numbers(x);
 11   console.log(numbers(x));
debug> next
< world
break in script_folder/myscript.js:10
  8  debugger;
  9  console.log('world');
>10   numbers(x);
 11   console.log(numbers(x));
 12   console.log('times!');

يمكنك أيضًا تخطي بقية الدالة الحالية إلى السطر التالي للاستدعاء مباشرة عن طريق out:

break in script_folder/myscript.js:10
  8  debugger;
  9  console.log('world');
>10   numbers(x);
 11   console.log(numbers(x));
 12   console.log('times!');
debug>
break in script_folder/myscript.js:4
  2 global.x = 5;
  3 function numbers(num) {
> 4   x++;
  5  return num;
  6 }
debug> out
break in script_folder/myscript.js:11
  9  console.log('world');
 10   numbers(x);
>11   console.log(numbers(x));
 12   console.log('times!');
 13   debugger;
debug>

ولكي تعرض نصوص الشيفرة التي تسبق وتلي نقطة التوقف الحالية، أدخل أمر list(5)‎ إذ إنَّ 5 هي عدد السطور التي ستُعرَض قبل وبعد نقطة التوقف:

break in script_folder/myscript.js:11
  9  console.log('world');
 10   numbers(x);
>11   console.log(numbers(x));
 12   console.log('times!');
 13   debugger;
debug> list(5)
  6 }
  7 setTimeout(() => {
  8  debugger;
  9  console.log('world');
 10   numbers(x);
>11   console.log(numbers(x));
 12   console.log('times!');
 13   debugger;
 14 }, 1000);
 15 console.log('hello');
 16 });
debug>

لكن هل يجب عليّ الدخول في وضع repl أو استخدام أمر exec كلما أردت معاينة قيمة متغير أو دالة ما؟ بالطبع لا، هنا يظهر دور الراصدات.

الراصدات Watchers

يمكننا رصد قيم تعابير الدوال والمتغيرات أثناء التنقيح، إذ يتم تقييم وعرض كل تعبير موجود في قائمة الراصدات عند كل نقطة توقف مباشرة قبل شيفرة نقطة التوقف.

لرصد تعبير معين، أضف التعبير إلى قائمة الراصدات عن طريق أمر watch('expr')‎ إذ إنَّ expr هو التعبير المُراد رصده، كما نرى من المثال التالي:

debug> watch('x')
debug> run
< Debugger listening on ws://127.0.0.1:9229/f9a9db17-725b-48d1-9c16-de2b5564498b
< For help see https://nodejs.org/en/docs/inspector
< Debugger attached.
Break on start in script_folder/myscript.js:1
Watchers:
  0: x =
    ReferenceError: x is not defined
        ...
> 1 (function (exports, require, module, __filename, __dirname) { // myscript.js
  2 global.x = 5;
  3 function numbers(num) {
debug> cont
< hello
break in script_folder/myscript.js:8
Watchers:
  0: x = 5
  6 }
  7 setTimeout(() => {
> 8   debugger;
  9  console.log('world');
 10   console.log(numbers(x));
debug> cont
< world
< 5
< times!
break in script_folder/myscript.js:12
Watchers:
  0: x = 6
 10   console.log(numbers(x));
 11   console.log('times!');
>12   debugger;
 13 }, 1000);
 14 console.log('hello');
debug>

أدخلنا x إلى قائمة الراصدات، ثم أعدنا تنفيذ الشيفرة، فظهرت رسالة خطأ بعدم وجود متغير x في نقطة التوقف الأولى التلقائية، لأنه لم يُعرَّف المتغير بعد، ثم في نقطة التوقف الثانية، أظهرت أولًا قيمة x قبل شيفرة نقطة التوقف، وفي نقطة التوقف الثالثة، أظهرت قيمة x وقد تغيرت بعد استدعاء دالة numbers. يمكنك بالطبع إضافة أكثر من عنصر إلى قائمة الراصدات، أضفنا هنا دالة numbers وأعدنا تشغيل الشيفرة:

debug> watch('numbers')
debug> restart
< Debugger listening on ws://127.0.0.1:9229/f9a9db17-725b-48d1-9c16-de2b5564498b
< For help see https://nodejs.org/en/docs/inspector
< Debugger attached.
Break on start in script_folder/myscript.js:1
Watchers:
  0: x =
    ReferenceError: x is not defined
        ...
  1: numbers = [Function: numbers]
> 1 (function (exports, require, module, __filename, __dirname) { // myscript.js
  2 global.x = 5;
  3 function numbers(num) {
debug> cont
< hello
break in script_folder/myscript.js:8
Watchers:
  0: x = 5
  1: numbers = [Function: numbers]
  6 }
  7 setTimeout(() => {
> 8   debugger;
  9  console.log('world');
 10   console.log(numbers(x));
debug> cont
< world
< 5
< times!
break in script_folder/myscript.js:12
Watchers:
  0: x = 6
  1: numbers = [Function: numbers]
 10   console.log(numbers(x));
 11   console.log('times!');
>12   debugger;
 13 }, 1000);
 14 console.log('hello');

نلاحظ هنا أن قائمة الراصدات لم تُظهر أي قيمة للدالة numbers في أي من نقاط التوقف السابقة بل اكتفت بذكر أنها دالة، وهذا لأنني لم أضفها بالشكل الصحيح، يجب إضافة الدالة بهذا الشكل numbers()‎ مع وضع وسيط في حالة ما إذا تطلبت الدالة ذلك. انظر المثال التالي:

debug> watch('numbers(x)')
debug> watch('numbers(3)')
debug> run
< Debugger listening on ws://127.0.0.1:9229/061a973f-98c0-46c9-a792-b3e640b07ae6
< For help see https://nodejs.org/en/docs/inspector
< Debugger attached.
Break on start in script_folder/myscript.js:1
Watchers:
  0: x =
    ReferenceError: x is not defined
        ...
  1: numbers = [Function: numbers]
  2: numbers(x) =
    ReferenceError: x is not defined
        ...
  3: numbers(3) =
    ReferenceError: x is not defined
        ...
> 1 (function (exports, require, module, __filename, __dirname) { // myscript.js
  2 global.x = 5;
  3 function numbers(num) {
debug> cont
< hello
break in script_folder/myscript.js:8
Watchers:
  0: x = 5
  1: numbers = [Function: numbers]
  2: numbers(x) = 5
  3: numbers(3) = 3
  6 }
  7 setTimeout(() => {
> 8   debugger;
  9  console.log('world');
 10   console.log(numbers(x));
debug> cont
< world
< 7
< times!
break in script_folder/myscript.js:12
Watchers:
  0: x = 8
  1: numbers = [Function: numbers]
  2: numbers(x) = 8
  3: numbers(3) = 3
 10   console.log(numbers(x));
 11   console.log('times!');
>12   debugger;
 13 }, 1000);
 14 console.log('hello');

الآن، أظهرت قائمة الراصدات قيمة دالة numbers بالمتغيرات المختلفة التي وضعناها في عدة نقاط توقف. الآن، لنزل numbers من قائمة الراصدات باستخدام unwatch :

debug> unwatch('numbers')
debug> run
< Debugger listening on ws://127.0.0.1:9229/c908d8a3-51f6-4acc-9e58-ee95223cbcfd
< For help see https://nodejs.org/en/docs/inspector
< Debugger attached.
Break on start in script_folder/myscript.js:1
Watchers:
  0: x =
    ReferenceError: x is not defined
        ...
  1: numbers(x) =
    ReferenceError: x is not defined
       ...
  2: numbers(3) =
    ReferenceError: x is not defined
      ...
> 1 (function (exports, require, module, __filename, __dirname) { // myscript.js
  2 global.x = 5;
  3 function numbers(num) {
debug> cont
< hello
break in script_folder/myscript.js:8
Watchers:
  0: x = 5
  1: numbers(x) = 5
  2: numbers(3) = 3
  6 }
  7 setTimeout(() => {
> 8   debugger;
  9  console.log('world');
 10   console.log(numbers(x));
debug> cont
< world
< 7
< times!
break in script_folder/myscript.js:12
Watchers:
  0: x = 8
  1: numbers(x) = 8
  2: numbers(3) = 3
 10   console.log(numbers(x));
 11   console.log('times!');
>12   debugger;
 13 }, 1000);
 14 console.log('hello');

يمكنك أيضًا عرض الراصدات عن طريق أمر watchers:

>13   debugger;
 14 }, 1000);
 15 console.log('hello');
debug> watchers
  0: x = 11
  1: numbers(x) = 11
   2: numbers(3) = 3
debug>

لإغلاق المنقّح، أدخل ‎.exit (لا تنس النقطة قبل كلمة exit):

 11   console.log('times!');
>12   debugger;
 13 }, 1000);
 14 console.log('hello');
debug> .exit
$

مرجع الأوامر

التقدم في الشيفرة

  • cont أو c: الاستمرار في تنفيذ الكود حتى نقطة التوقف التالية.
  • next أو n: الانتقال إلى الخطوة التالية مباشرة في تنفيذ الكود.
  • step أو s: التعمق في الدالة الفرعية التالية مباشرة.
  • out أو o: الانتقال إلى الخطوة التالية في مسار التنفيذ الرئيسي.
  • pause: إيقاف تنفيذ الكود (مثل زر الإيقاف في أدوات المطوّر في متصفحات الويب).

نقاط التوقف

  • setBreakpoint()‎ أو sb()‎: وضع نقطة توقف في السطر الحالي.
  • setBreakpoint(line)‎ أو sb(line)‎: وضع نقطة توقف في سطر معين، حيث line هو رقم السطر.
  • setBreakpoint(function())‎ أو sb(...)‎: وضع نقطة التوقف عند أول استدعاء لدالة معينة، حيث function()‎ هي الدالة التي نريد استدعاءها.
  • setBreakpoint('script.js', 1)‎ أو sb(...)‎: وضع نقطة التوقف في سطر معين من ملف محدد، وهو في هذا المثال السطر الأول من الملف script.js.
  • clearBreakpoint('script.js', 1)‎ أو cb(...)‎: إزالة نقطة التوقف من سطر معين في ملف محدد، وهو في هذا المثال السطر الأول من الملف script.js.

يمكنك أيضًا تحديد نقطة توقف في ملف (وحدة [[[Node.js/modules|module]]]) لم يُحمَّل بعد. في المثال التالي، حدَّدنا نقطة توقف في ملف mod.js في السطر 2، طبعًا سيظهر لك في البداية تحذير أن ملف mod.js لم يُحمَّل بعد، يمكنك تجاهله:

$ node inspect main.js
< Debugger listening on ws://127.0.0.1:9229/4e3db158-9791-4274-8909-914f7facf3bd
< For help, see: https://nodejs.org/en/docs/inspector
< Debugger attached.
Break on start in main.js:1
> 1 (function (exports, require, module, __filename, __dirname) { const mod = require('./mod.js');
  2 mod.hello();
  3 mod.hello();
debug> setBreakpoint('mod.js', 22)
Warning: script 'mod.js' was not loaded yet.
debug> c
break in mod.js:22
 20 // USE OR OTHER DEALINGS IN THE SOFTWARE.
 21
>22 exports.hello = function() {
 23   return 'hello from module';
 24 };
debug>

إظهار المعلومات

  • backtrace أو bt: طباعة قائمة تتبع إطار التنفيذ الحالي (current execution frame).
  • list(5)‎: إظهار الشيفرة بعدد من السطور قبل وبعد نقطة التوقف الحالية (حيث 5 هي عدد السطور قبل وبعد).
  • watch(expr)‎: إضافة تعبير إلى قائمة الراصدات.
  • unwatch(expr)‎: إزالة تعبير من قائمة الراصدات.
  • watchers: عرض قائمة الراصدات.
  • repl: تفعيل وحدة REPL للمنقّح لتقييم تعبيرٍ برمجيٍ في سياق الشيفرة التي يجري تنقيحها.
  • exec expr: تنفيذ تعبير في سياق الشيفرة التي يجري تنفيذها.

أدوات التحكم بالتنفيذ

  • run: تشغيل الشيفرة (تعمل تلقائيًا عند بداية المنقّح).
  • restart: إعادة تشغيل الشيفرة.
  • kill: قتل الشيفرة نهائيًا.

أوامر متنوعة

  • scripts: عرض جميع الملفات التي تم تحميلها.
  • version: عرض رقم إصدار V8 المستخدمة.

الاستخدام المتقدم

دمج محقق V8 مع node.js

يسمح دمج محقق V8 باستخدام أدوات المطور في متصفح Chrome لملفات Node.js من أجل التنقيح والتشخيص. حيث يستخدم بروتوكول أدوات مطور Chrome.

يمكن تفعيل محقق  Chrome بتمرير الخيار ‎--inspect عند بدء تطبيق Node.js. ومن الممكن أيضًا توفير منفذ مخصص باستخدام هذا الخيار (على سبيل المثال ‎--inspect-9222 سيقبل بتوصيلات أدوات المطور على منفذ 9222).

للتوقف عند السطر الأول من شيفرة التطبيق، مرر الخيار ‎--inpect-brk بدلًا من ‎--inspect:

$ node --inspect index.js
Debugger listening on 127.0.0.1:9229.
To start debugging, open the following URL in Chrome:
   chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9229/dc9010dd-f8b8-4ac5-a510-c1a114ec7d29

يوفر لك المنقّح رابطًا تستطيع الدخول إليه في Chrome للبدء بعملية التنقيح باستخدام أدوات المطور في Chrome.

لاحظ أنه في المثال العلوي، تم إنتاج المعرف الفريد العالمي UUID الموجود في نهاية الرابط dc9010dd-f8b8-4ac5-a510-c1a114ec7d29 بشكل مؤقت، إذ ستغير في كل جلسة تنقيح.

مصادر