練習 - 使用 Node.js 內建偵錯工具

已完成

為了實際執行您剛才看到的偵錯概念,您將建立簡短的 Node.js 應用程式,以計算 Fibonacci 序列的第 N 個數目。

Fibonacci 數列是一組以 0 和 1 開頭的數字,每個後續的數字都是前兩個數字的和。 序列會以這種方式繼續下去:

0, 1, 1, 2, 3, 5, 8, 13, 21...

讓我們建立新的 Node.js 應用程式來說明概念。

在開發容器中開啟專案

此訓練模組會在瀏覽器中或本機計算機提供開發容器。 此容器提供所有必要的環境,因此您可以使用此訓練模組,而不需要安裝IDE或 Node.js。 您不需要知道容器的任何專案,即可完成此訓練課程模組。

  • 遠端開發 (瀏覽器)
  • 本機開發 (Docker)
  1. 開始在 MicrosoftDocs/node-essentials GitHub 存放庫分的 main 分支上建立新的 GitHub Codespace 的流程。

  2. [建立 Codespace] 頁面上,檢閱 Codespace 組態設定,然後選取 [建立 Codespace]

    Screenshot of the confirmation screen before creating a new codespace.

  3. 等候 Codespace 開始。 此啟動程序可能需要幾分鐘的時間。

  4. 在 Codespace 中開啟新的終端機。

    提示

    您可以使用主功能表瀏覽至 [終端機] 功能表選項,然後選取 [新終端機] 選項。

    Screenshot of the codespaces menu option to open a new terminal.

  5. 驗證您的環境中已安裝 Node.js:

    node --version
    

    開發容器會使用 Node.js LTS 版本。 確切的版本可能不同。

  6. 此專案中的其餘練習會在此開發容器的內容中進行。

準備環境

在開始練習之前,我們要先準備好程式碼與環境。

  1. 開啟 ./nodejs-debug 子資料夾,然後建立名為 myfibonacci.js 的新 JavaScript 檔案。 資料夾中已經存在的檔案是練習的解決方案,修正偵錯期間發現的錯誤所需的修正。

  2. 請在檔案中貼上此程式碼:

    function fibonacci(n) {
      let n1 = 0;
      let n2 = 1;
      let sum = 0;
    
      for (let i = 2; i < n; i++) {
        sum = n1 + n2;
        n1 = n2;
        n2 = sum;
      }
    
      return n === 0 ? n1 : n2;
    }
    
    const result = fibonacci(5);
    console.log(result);
    
  3. 儲存盤案 CTRL + S。

  4. 以滑鼠右鍵按鍵單擊 ./nodejs-debug 子資料夾,然後使用下列命令選取 Open in integrated terminal 並執行程式:

    node fibonacci.js
    

應用程式應該會在控制台中顯示結果 3 (三個)。 糟糕,看來似乎有一個錯誤 (Bug),因為我們原本預期看見的是 5 (五) 結果。 讓我們使用 Node.js 內建偵錯工具來了解出了什麼問題。

調試程式命令速查表

Node.js 內建調試程式隨附一組命令,可用來控制程序的執行。 以下是最常見命令的快速速查表:

Command 描述
c 繼續。 繼續執行,直到下一個中斷點或程式結束為止。
next 逐程序。 此命令類似於 step 命令,不同之處在於,如果下一行程式代碼是函式呼叫,它會執行函式而不逐步執行函式。
s 逐步執行。 此命令與next 命令類似,不同之處在於,如果下一行程式代碼是函數調用,請移至此函式程序代碼的第一行。
sb() 在目前的行新增中斷點。
exec <EXPR> 評估目前執行內容內的運算式。 此命令有助於您取得目前狀態的相關資訊。 例如,您可以使用 exec i 來取得名為 i 之變數的值。
Ctrl + D 停止偵錯工具。

啟動內建偵錯工具

在啟用內建偵錯工具之後,再次啟動程式。 在終端中輸入此命令:

node inspect fibonacci.js

在終端機中,您應該會看到偵錯工具的提示顯示。 現在,執行 s + <Enter> 程式代碼,直到執行點位於函式開頭 fibonacci 為止,如下所示:

break in fibonacci.js:2
  1 function fibonacci(n) {
> 2   let n1 = 0;
  3   let n2 = 1;
  4   let sum = 0;
debug>

目前我們可執行下列命令,來檢查函式中傳遞的 n 參數值:

exec n

您應在主控台中看到 5 (五) 顯示為結果。 繼續執行 s 命令以逐步執行程式碼,直到執行點位於迴圈開頭為止。 使用 s 命令需要五個步驟才能觸達此執行點:

break in fibonacci.js:7
  5
  6   for (let i = 2; i < n; i++) {
> 7     sum = n1 + n2;
  8     n1 = n2;
  9     n2 = sum;
debug>

注意

您可能已經注意到,需要使用偵錯命令多次逐步執行,才能通過 for(...) {} 代碼行。 此情況之所以會發生,是因為此行上有多個「陳述式」。 當您逐步執行時,您會移至程式碼中的下一個陳述式。 通常每行會有一個陳述式。 如果情況不是這樣,則須多次逐步執行才能移至下一行。

使用中斷點找出錯誤 (Bug)

現在讓我們在此行新增中斷點,以便快速地進行迴圈反覆運算。 在終端機中輸入下列命令:

sb()

您應該會在主控台中看到相同的行再次顯示,這表示已在此行設定中斷點。 當目前的執行點移動時,您會在設定中斷點的那一行看到星號 *

在終端中執行 c 命令以前進到下一次迴圈反覆運算:

c

我們會使用 exec 命令檢查目前反覆運算狀態,並使用陣列作為命令參數來查看多個變數值。 若要查看反覆運算器 i 和總計 sum 的值,則我們會使用語法 [i, sum]。 在終端中輸入此命令:

exec [i, sum]

您應該會在主控台中看到 [ 3, 1 ] 此結果。

程式碼尚未更新目前反覆運算的 sum 變數值,即 3 (三)。 變數 sum 的值仍然會顯示前一個反覆運算的 Fibonacci 數字。 以下是我們在程式碼中用來取得目前 sum 值的計算:

fibonacci(2) = fibonacci(0) + fibonacci(1)
             = 0 + 1
             = 1

根據我們的計算,我們的程式似乎已正確執行到這一點。

在終端中執行 c 命令,然後再次檢查狀態,以繼續進行下一次迴圈反覆執行:

c
exec [i, sum]

您應該會在主控台中看到 [ 4, 2 ] 此結果。

現在我們已位於我們感興趣的反覆運算數字 (也就是 5 (五)) 之前的位置。 為了謹慎起見,使用 s 命令來逐步執行此反覆運算。 嘗試前往先前的中斷點,但是以一次執行一個步驟的方式進行。 不要超越中斷點!

發生什麼事?

修正 Bug

在檢查迴圈條件 i < n 之後,執行突然跳到具有 return 命令的代碼行。 以下是您應該在終端中看到的內容:

break in fibonacci.js:12
 10   }
 11
>12   return n === 0 ? n1 : n2;
 13 }
 14

就這麼簡單,我們找到 Bug 了! 程式碼不會更新反覆運算 5 (五) 的總和,而是直接跳出迴圈。 這就是我們在初始執行中取得先前的反覆運算結果 3 (三) 的原因。

我們需要修正 fibonacci.js 程式碼中的迴圈條件。 在程式碼編輯器中,將測試陳述式的值從少於 < 變更為少於或等於 <=

for (let i = 2; i <= n; i++) {
  sum = n1 + n2;
  n1 = n2;
  n2 = sum;
}

在程式碼編輯器中儲存變更,然後選取 Ctrl+D 以結束偵錯工具。

現在在終端中再次執行您的程式:

node fibonacci.js

您現在應該會看到預期的結果顯示在主控台中,也就是 5 (五)。

您可以使用 Node.js 中的內建偵錯工具來了解基本的偵錯原則,以及進行快速的偵錯工作階段。 每次都要輸入命令可能會有點麻煩,而且搭配複雜應用程式使用時,其功能可能太少且難以使用。

我們將在後續小節查看如何改為使用 Visual Studio Code 偵錯工具。