Jak debugować kod Node.js przy użyciu wielu narzędzi
Opublikowany: 2022-03-15Node.js to środowisko uruchomieniowe JavaScript oparte na tym samym silniku V8, który jest używany w przeglądarce Google Chrome. Jest często używany do tworzenia wieloplatformowych aplikacji serwerowych i terminalowych. Node.js stał się coraz bardziej popularny w ciągu ostatniej dekady, ponieważ jest łatwy w instalacji, praktyczny w użyciu, szybki i umożliwia programistom internetowym po stronie klienta wykorzystanie ich umiejętności gdzie indziej.
Jednak tworzenie oprogramowania pozostaje złożonym zadaniem, a Twój kod Node.js w pewnym momencie zawiedzie. W tym samouczku przedstawiono różne narzędzia ułatwiające debugowanie aplikacji i znajdowanie przyczyny problemu.
Zanurzmy się od razu.
Omówienie debugowania
„Debugowanie” to nazwa nadana różnym sposobom naprawiania wad oprogramowania. Naprawienie błędu jest często proste. Znalezienie przyczyny błędu może być znacznie bardziej skomplikowane i pociągać za sobą wiele godzin drapania się po głowie.
Poniższe sekcje opisują trzy ogólne typy błędów, które napotkasz.
Błędy składni
Twój kod nie jest zgodny z regułami języka — na przykład, gdy pominiesz nawias zamykający lub błędnie napiszesz instrukcję, taką jak console.lag(x)
.
Dobry edytor kodu może pomóc w wykryciu typowych problemów poprzez:
- Oznaczenia kolorami prawidłowe lub nieprawidłowe stwierdzenia
- Zmienne sprawdzające typ
- Automatyczne uzupełnianie nazw funkcji i zmiennych
- Podświetlanie pasujących nawiasów
- Automatyczne wcinanie bloków kodu
- Wykrywanie nieosiągalnego kodu
- Refaktoryzacja niechlujnych funkcji
Darmowe edytory, takie jak VS Code i Atom, mają świetne wsparcie dla Node.js, JavaScript i TypeScript (który jest przenoszony do JavaScript). Podstawowe problemy ze składnią można zazwyczaj wykryć przed zapisaniem i przetestowaniem kodu.
Linter kodu, taki jak ESLint, będzie również zgłaszał błędy składni, złe wcięcia i niezadeklarowane zmienne. ESLint to narzędzie Node.js, które możesz zainstalować globalnie za pomocą:
npm i eslint -g
Możesz sprawdzić pliki JavaScript z wiersza poleceń za pomocą:
eslint mycode.js
…ale łatwiej jest użyć wtyczki edytora, takiej jak ESLint dla VS Code lub linter-eslint dla Atom, które automatycznie weryfikują kod podczas pisania:

Błędy logiczne
Twój kod działa, ale nie działa zgodnie z oczekiwaniami. Na przykład użytkownik nie jest wylogowany, gdy o to poprosi; raport zawiera nieprawidłowe liczby; dane nie są w pełni zapisywane w bazie danych; itp.
Błędy logiczne mogą być spowodowane przez:
- Używanie niewłaściwej zmiennej
- Nieprawidłowe warunki, np.
if (a > 5)
zamiastif (a < 5)
- Obliczenia, które nie uwzględniają pierwszeństwa operatorów, np.
1+2*3
, dają 7 zamiast 9.
Błędy wykonania (lub wykonania)
Błąd staje się widoczny dopiero po uruchomieniu aplikacji, co często prowadzi do awarii. Błędy uruchomieniowe mogą być spowodowane przez:
- Dzielenie przez zmienną, która została ustawiona na zero
- Próba uzyskania dostępu do elementu tablicy, który nie istnieje
- Próbuję pisać do pliku tylko do odczytu
Błędy logiczne i błędy wykonawcze są trudniejsze do wykrycia, chociaż pomocne mogą być następujące techniki programistyczne:
- Użyj programowania sterowanego testami: TTD zachęca do pisania testów przed opracowaniem funkcji, np. X jest zwracane z funkcji Y, gdy Z jest przekazywane jako parametr. Testy te są uruchamiane podczas początkowego opracowywania i kolejnych aktualizacji, aby zapewnić, że kod nadal działa zgodnie z oczekiwaniami.
- Użyj systemu śledzenia problemów: Nie ma nic gorszego niż wiadomość e-mail z informacją „Twoje oprogramowanie nie działa” ! Systemy śledzenia problemów pozwalają rejestrować określone problemy, etapy powielania dokumentów, określać priorytety, przypisywać programistów i śledzić postęp poprawek.
- Użyj kontroli źródła: system kontroli źródła, taki jak Git, pomoże Ci wykonać kopię zapasową kodu, zarządzać wersjami i określić, gdzie został wprowadzony błąd. Repozytoria online, w tym Github i Bitbucket, zapewniają wolną przestrzeń i narzędzia dla mniejszych projektów lub projektów typu open source.
Nadal będziesz napotykać błędy Node.js, ale poniższe sekcje opisują sposoby zlokalizowania tego nieuchwytnego błędu.
Ustaw odpowiednie zmienne środowiskowe Node.js
Zmienne środowiskowe ustawione w systemie operacyjnym hosta mogą kontrolować ustawienia aplikacji i modułów Node.js. Najczęstszym jest NODE_ENV
, który zwykle jest ustawiony na programowanie podczas debugowania lub produkcji podczas uruchamiania na aktywnym serwerze. Ustaw zmienne środowiskowe w systemie macOS lub Linux za pomocą polecenia:
NODE_ENV=development
lub w (klasycznym) wierszu poleceń systemu Windows:
set NODE_ENV=development
lub Windows Powershell:
$env:NODE_ENV="development"
W popularnym frameworku Express.js ustawienie NODE_ENV na programowanie wyłącza buforowanie plików szablonów i wyświetla szczegółowe komunikaty o błędach, które mogą być pomocne podczas debugowania. Inne moduły mogą oferować podobne funkcje i możesz dodać warunek NODE_ENV do swoich aplikacji, np.
// running in development mode? const devMode = (process.env.NODE_ENV !== 'production'); if (devMode) { console.log('application is running in development mode'); }
Możesz również użyć metody Node'a util.debuglog do warunkowego wyprowadzania komunikatów o błędach, np.
import { debuglog } from 'util'; const myappDebug = debuglog('myapp'); myappDebug('log something');
Ta aplikacja wyświetli komunikat dziennika tylko wtedy, gdy NODE_DEBUG jest ustawione na myapp lub symbol wieloznaczny, taki jak * lub my*.
Użyj opcji wiersza poleceń Node.js
Skrypty węzłowe są zwykle uruchamiane z węzłem, po którym następuje nazwa skryptu wejściowego:
node app.js
Możesz także ustawić opcje wiersza poleceń, aby kontrolować różne aspekty środowiska wykonawczego. Przydatne flagi do debugowania obejmują:
-
--check
sprawdź składnię skryptu bez wykonywania -
--trace-warnings
wypisz ślad stosu, gdy obietnice JavaScript nie zostaną rozwiązane lub odrzucone -
--enable-source-maps
pokaż mapy źródłowe podczas korzystania z transpilera, takiego jak TypeScript -
--throw-deprecation
ostrzegaj, gdy używane są przestarzałe funkcje Node.js -
--redirect-warnings=file
wyświetlaj ostrzeżenia do pliku, a nie na stderr -
--trace-exit
wyprowadza ślad stosu, gdy wywoływana jestprocess.exit()
.
Wysyłaj wiadomości do konsoli
Wysłanie komunikatu konsoli jest jednym z najprostszych sposobów debugowania aplikacji Node.js:
console.log(`someVariable: ${ someVariable }`);
Niewielu programistów zdaje sobie sprawę, że istnieje wiele innych metod konsoli:
Metoda konsoli | Opis |
---|---|
.log(msg) | standardowy komunikat konsoli |
.log('%j', obj) | obiekt wyjściowy jako kompaktowy ciąg JSON |
.dir(obj, opt) | ładne-drukowanie właściwości obiektu |
.table(obj) | tablice wyjściowe i obiekty w formacie tabelarycznym |
.error(msg) | komunikat o błędzie |
.count(label) | zwiększyć nazwany licznik i wyjście |
.countReset(label) | zresetować nazwany licznik |
.group(label) | wcięcie grupy wiadomości |
.groupEnd(label) | zakończyć grupę |
.time(label) | uruchamia nazwany timer |
.timeLog(label) | zgłasza upływ czasu |
.timeEnd(label) | zatrzymuje nazwanego timera |
.trace() | wypisz ślad stosu (listę wszystkich wykonanych wywołań funkcji) |
.clear() | wyczyść konsolę |
console.log()
akceptuje również listę wartości oddzielonych przecinkami:
let x = 123; console.log('x:', x); // x: 123
…chociaż destrukturyzacja ES6 oferuje podobne wyniki przy mniejszym wysiłku:
console.log({ x }); // { x: 123 }
Komenda console.dir() pretty-wypisuje właściwości obiektu w taki sam sposób jak util.inspect():
console.dir(myObject, { depth: null, color: true });
Kontrowersje konsoli
Niektórzy programiści twierdzą, że nigdy nie należy używać console.log()
, ponieważ:
- Zmieniasz kod i możesz coś zmienić lub zapomnieć go usunąć, oraz
- Nie ma potrzeby, gdy istnieją lepsze opcje debugowania.
Nie wierz nikomu, kto twierdzi, że nigdy nie używa console.log()
! Logowanie jest szybkie i brudne, ale wszyscy w pewnym momencie z niego korzystają. Użyj dowolnego narzędzia lub techniki, które preferujesz. Naprawienie błędu jest ważniejsze niż metoda, którą zastosujesz, aby go znaleźć.
Użyj systemu rejestrowania innej firmy
Systemy rejestrowania innych firm zapewniają bardziej zaawansowane funkcje, takie jak poziomy wiadomości, szczegółowość, sortowanie, wyjście plików, profilowanie, raportowanie i inne. Popularne rozwiązania to: kabina, loglevel, morgan, pino, signale, storyboard, tracer i winston.
Użyj inspektora V8
Silnik JavaScript V8 zapewnia klienta debugowania, którego można używać w Node.js. Uruchom aplikację za pomocą inspekcji węzła, np.
node inspect app.js
Debuger zatrzymuje się w pierwszym wierszu i wyświetla monit debug>:
$ node inspect .\mycode.js < Debugger listening on ws://127.0.0.1:9229/143e23fb < For help, see: https://nodejs.org/en/docs/inspector < ok < Debugger attached. < Break on start in mycode.js:1 > 1 const count = 10; 2 3 for (i = 0; i < counter; i++) { debug>
Wejdź do pomocy, aby wyświetlić listę poleceń. Możesz przejść przez aplikację wpisując:
- cd lub c : kontynuuj wykonywanie
- next lub n : uruchom następne polecenie
- step or s : przejdź do wywoływanej funkcji
- out lub o : wyjdź z funkcji i wróć do instrukcji wywołującej
- pauza : wstrzymaj uruchamianie kodu
- watch('myvar') : obserwuj zmienną
- setBreakPoint() lub sb() : ustaw punkt przerwania
- restart : uruchom ponownie skrypt
- .exit lub Ctrl | Cmd + D : wyjdź z debugera
Trzeba przyznać, że ta opcja debugowania jest czasochłonna i nieporęczna. Używaj go tylko wtedy, gdy nie ma innej opcji, na przykład gdy uruchamiasz kod na zdalnym serwerze i nie możesz połączyć się z innego miejsca lub zainstalować dodatkowe oprogramowanie.
Użyj przeglądarki Chrome do debugowania kodu Node.js
Opcja inspekcji Node.js użyta powyżej uruchamia serwer Web Socket, który nasłuchuje na porcie localhost 9229. Uruchamia również tekstowego klienta debugowania, ale możliwe jest użycie klientów graficznych — takich jak ten wbudowany w Google Chrome i oparty na Chrome przeglądarki takie jak Chromium, Edge, Opera, Vivaldi i Brave.
Aby debugować typową aplikację internetową, uruchom ją z opcją –inspect, aby włączyć serwer Web Socket debugera V8:
node --inspect index.js
Notatka:
- Przypuszcza się, że index.js jest skryptem wejściowym aplikacji.
- Upewnij się, że używasz
--inspect
z podwójnymi myślnikami, aby upewnić się, że nie uruchamiasz klienta debugera tekstowego. - Możesz użyć nodemon zamiast node, jeśli chcesz automatycznie ponownie uruchomić aplikację po zmianie pliku.
Domyślnie debuger akceptuje tylko połączenia przychodzące z komputera lokalnego. Jeśli uruchamiasz aplikację na innym urządzeniu, maszynie wirtualnej lub kontenerze Docker, użyj:

node --inspect=0.0.0.0:9229 index.js

Możesz również użyć --inspect-brk
zamiast --inspect
, aby zatrzymać przetwarzanie (ustawić punkt przerwania) w pierwszym wierszu, dzięki czemu możesz przejść przez kod od początku.
Otwórz przeglądarkę opartą na Chrome i wpisz chrome://inspect
w pasku adresu, aby wyświetlić urządzenia lokalne i sieciowe:

Jeśli Twoja aplikacja Node.js nie pojawia się jako zdalny cel , albo:
- Kliknij Otwórz dedykowane DevTools dla węzła i wybierz adres i port, lub
- Zaznacz Wykryj cele sieciowe , kliknij Konfiguruj , a następnie dodaj adres IP i port urządzenia, na którym jest uruchomione.
Kliknij łącze inspekcji obiektu docelowego, aby uruchomić klienta debugera DevTools. Powinno to być znane każdemu, kto używał DevTools do debugowania kodu po stronie klienta:

Przejdź do panelu Źródła . Możesz otworzyć dowolny plik, naciskając Cmd | Ctrl + P i wpisanie jego nazwy pliku (np. index.js).
Jednak łatwiej jest dodać folder projektu do obszaru roboczego. Dzięki temu możesz ładować, edytować i zapisywać pliki bezpośrednio z DevTools (czy uważasz, że to dobry pomysł, to inna sprawa!)
- Kliknij + Dodaj folder do obszaru roboczego
- Wybierz lokalizację swojego projektu Node.js
- Kliknij Zgadzam się , aby zezwolić na zmiany plików
Możesz teraz ładować pliki z drzewa katalogów po lewej stronie:

Kliknij dowolny numer wiersza, aby ustawić punkt przerwania oznaczony niebieskim znacznikiem.
Debugowanie opiera się na punktach przerwania . Określają one, gdzie debugger powinien wstrzymać wykonywanie programu i pokazywać bieżący stan programu (zmienne, stos wywołań itp.)
W interfejsie użytkownika można zdefiniować dowolną liczbę punktów przerwania. Inną opcją jest umieszczenie debuggera; do kodu, który zatrzymuje się po dołączeniu debugera.
Załaduj i użyj aplikacji internetowej, aby uzyskać dostęp do instrukcji, w której ustawiono punkt przerwania. W przykładzie tutaj http://localhost:3000/ jest otwierany w dowolnej przeglądarce, a DevTools zatrzyma wykonywanie w wierszu 44:

Panel po prawej stronie pokazuje:
- Rząd ikon akcji (patrz poniżej).
- Okienko Watch umożliwia monitorowanie zmiennych poprzez kliknięcie ikony + i wprowadzenie ich nazw.
- Okienko Punkty przerwania zawiera listę wszystkich punktów przerwania i umożliwia ich włączanie lub wyłączanie.
- Okienko zakresu pokazuje stan wszystkich zmiennych lokalnych, modułowych i globalnych. Najczęściej będziesz sprawdzać tę szybę.
- Okienko stosu wywołań pokazuje hierarchię funkcji wywoływanych w celu osiągnięcia tego punktu.
Powyżej pokazany jest rząd ikon akcji Wstrzymano w punkcie przerwania :

Od lewej do prawej wykonują one następujące czynności:
- wznowienie wykonywania : Kontynuuj przetwarzanie do następnego punktu przerwania
- step over : Wykonaj następne polecenie, ale pozostań w bieżącym bloku kodu — nie przeskakuj do żadnej wywołanej funkcji
- step into : Wykonaj następne polecenie i w razie potrzeby przejdź do dowolnej funkcji
- step out : Kontynuuj przetwarzanie do końca funkcji i wróć do polecenia wywołującego
- krok : Podobny do kroku do , z wyjątkiem tego, że nie przeskoczy do funkcji asynchronicznych
- dezaktywuj wszystkie punkty przerwania
- pauza przy wyjątkach : Zatrzymuje przetwarzanie w przypadku wystąpienia błędu.
Warunkowe punkty przerwania
Czasami konieczne jest sprawowanie większej kontroli nad punktami przerwania. Wyobraź sobie, że masz pętlę, która wykonała 1000 iteracji, ale interesuje Cię tylko stan ostatniej:
for (let i = 0; i < 1000; i++) { // set breakpoint here }
Zamiast klikać wznawianie wykonania 999 razy, możesz kliknąć prawym przyciskiem myszy linię, wybrać Dodaj warunkowy punkt przerwania i wprowadzić warunek, taki jak i = 999
:

Chrome wyświetla warunkowe punkty przerwania w kolorze żółtym, a nie niebieskim. W takim przypadku punkt przerwania jest wyzwalany tylko w ostatniej iteracji pętli.
Punkty logowania
Log Points skutecznie implementują console.log() bez żadnego kodu! Wyrażenie może zostać wyprowadzone, gdy kod wykonuje dowolny wiersz, ale nie zatrzymuje przetwarzania, w przeciwieństwie do punktu przerwania.
Aby dodać punkt logu, kliknij prawym przyciskiem myszy dowolną linię, wybierz Dodaj punkt logu i wprowadź wyrażenie, np. 'loop counter i', i
:

Konsola DevTools wyświetla loop counter i: 0
do loop counter i: 999
w powyższym przykładzie.
Użyj kodu VS do debugowania aplikacji Node.js
VS Code lub Visual Studio Code to darmowy edytor kodu firmy Microsoft, który stał się popularny wśród programistów internetowych. Aplikacja jest dostępna dla systemów Windows, macOS i Linux i jest rozwijana przy użyciu technologii internetowych w ramach platformy Electron.
VS Code obsługuje Node.js i ma wbudowanego klienta debugowania. Większość aplikacji można debugować bez żadnej konfiguracji; edytor automatycznie uruchomi serwer i klient debugujący.
Otwórz plik startowy (np. index.js), aktywuj okienko Uruchom i debuguj , kliknij przycisk Uruchom i debuguj i wybierz środowisko Node.js. Kliknij dowolną linię, aby aktywować punkt przerwania przedstawiony jako ikona czerwonego okręgu. Następnie otwórz aplikację w przeglądarce jak poprzednio — VS Code zatrzymuje wykonywanie po osiągnięciu punktu przerwania:

Okienka Zmienne , Obserwacja , Stos wywołań i Punkty przerwania są podobne do tych wyświetlanych w Chrome DevTools. Panel Załadowane skrypty pokazuje, które skrypty zostały załadowane, chociaż wiele z nich jest wewnętrznych w Node.js.
Pasek narzędzi ikon akcji umożliwia:
- wznowienie wykonywania : Kontynuuj przetwarzanie do następnego punktu przerwania
- step over : Wykonaj następne polecenie, ale pozostań w bieżącej funkcji — nie przeskakuj do żadnej wywołanej funkcji
- step into : Wykonaj następne polecenie i przejdź do dowolnej wywołanej funkcji
- step out : Kontynuuj przetwarzanie do końca funkcji i wróć do polecenia wywołującego
- uruchom ponownie aplikację i debugger
- zatrzymaj aplikację i debugger
Podobnie jak w przypadku Chrome DevTools, możesz kliknąć prawym przyciskiem myszy dowolny wiersz, aby dodać warunkowe punkty przerwania i punkty dziennika .
Aby uzyskać więcej informacji, zobacz debugowanie w Visual Studio Code.
Zaawansowana konfiguracja debugowania programu VS Code
Dalsza konfiguracja VS Code może być konieczna, jeśli chcesz debugować kod na innym urządzeniu, maszynie wirtualnej lub musisz użyć alternatywnych opcji uruchamiania, takich jak nodemon.
VS Code przechowuje konfiguracje debugowania w pliku .vscode
w katalogu .vscode w projekcie. Otwórz okienko Uruchom i debuguj, kliknij Utwórz plik launch.json i wybierz środowisko Node.js , aby wygenerować ten plik. Podana jest przykładowa konfiguracja:

Dowolna ilość ustawień konfiguracyjnych może być zdefiniowana jako obiekty w tablicy "configurations"
. Kliknij Dodaj konfigurację… i wybierz odpowiednią opcję.
Indywidualna konfiguracja Node.js może:
- Uruchom sam proces lub
- Dołącz do debugującego serwera Web Socket, być może działającego na zdalnym komputerze lub kontenerze Dockera.
Na przykład, aby zdefiniować konfigurację węzła, wybierz Node.js: Konfiguracja węzła i w razie potrzeby zmień skrypt wejściowy „program”:
{ // custom configuration "version": "0.2.0", "configurations": [ { "console": "integratedTerminal", "internalConsoleOptions": "neverOpen", "name": "nodemon", "program": "${workspaceFolder}/index.js", "request": "launch", "restart": true, "runtimeExecutable": "nodemon", "skipFiles": [ "<node_internals>/**" ], "type": "pwa-node" } ] }
Zapisz plik launch.json
, a nodemon (nazwa konfiguracji) pojawi się na liście rozwijanej u góry okienka Uruchom i debuguj . Kliknij zieloną ikonę uruchamiania, aby rozpocząć korzystanie z tej konfiguracji i uruchomić aplikację za pomocą nodemon:

Tak jak poprzednio, możesz dodać punkty przerwania, warunkowe punkty przerwania i punkty dziennika. Główna różnica polega na tym, że nodemon automatycznie zrestartuje serwer po zmodyfikowaniu pliku.
Aby uzyskać więcej informacji, zobacz konfiguracje VS Code Launch.
Następujące rozszerzenia programu VS Code mogą również pomóc w debugowaniu kodu hostowanego w środowiskach serwerów zdalnych lub izolowanych:
- Zdalne — Kontenery: Połącz się z aplikacjami uruchomionymi w kontenerach Docker
- Zdalny — SSH: Połącz się z aplikacjami działającymi na zdalnym serwerze
- Zdalny — WSL: Połącz się z aplikacjami działającymi w podsystemie Windows dla systemu Linux (WSL).
Inne opcje debugowania Node.js
Przewodnik debugowania Node.js zawiera porady dotyczące różnych edytorów tekstu i środowisk IDE, w tym Visual Studio, JetBrains WebStorm, Gitpod i Eclipse. Atom oferuje rozszerzenie do debugowania węzłów, które integruje debuger Chrome DevTools z edytorem.
Po uruchomieniu aplikacji możesz rozważyć skorzystanie z komercyjnych usług debugowania, takich jak LogRocket i Sentry.io, które mogą rejestrować i odtwarzać błędy klienta i serwera napotykane przez prawdziwych użytkowników.
Streszczenie
Historycznie debugowanie JavaScriptu było trudne, ale w ciągu ostatniej dekady nastąpiły ogromne ulepszenia. Wybór jest równie dobry — jeśli nie lepszy — niż w przypadku innych języków.
Użyj dowolnego narzędzia, aby zlokalizować problem. Nie ma nic złego w console.log() do szybkiego wyszukiwania błędów, ale Chrome DevTools lub VS Code mogą być preferowane w przypadku bardziej złożonych problemów. Narzędzia mogą pomóc w tworzeniu bardziej niezawodnego kodu i poświęcić mniej czasu na naprawianie błędów.
Na jaką praktykę debugowania Node.js przysięgasz? Udostępnij w sekcji komentarzy poniżej!