Esperienza di debug moderno parte 2


Nella parte 1, abbiamo visto come scrivere ed eseguire JavaScript usando DevTools. Nella parte 2, esamineremo il debug di JavaScript e adotteremo un flusso di lavoro tale che la risoluzione degli errori JavaScript e la diagnosi dei problemi diventino più efficienti.

Debug di JavaScript utilizzando DevTools

Parola chiave del debugger

È possibile utilizzare la parola chiave debugger direttamente nel codice per richiamare le funzionalità di debug (se presenti) del runtime JavaScript. L'effetto dell'aggiunta della parola chiave debugger nel codice è identico all'impostazione manuale di un punto di interruzione tramite l'interfaccia utente di DevTools. In Chrome, il debugger la parola chiave non ha alcun effetto mentre DevTools è chiuso.

Controlli del debugger

I controlli del debugger forniscono un controllo a grana fine sul flusso di debug. Utilizzali quando ti fermi a un punto di interruzione per navigare efficacemente attraverso il codice JavaScript. Ogni controllo del debugger elencato in questa sezione corrisponde a un pulsante nel DevTools che è possibile selezionare durante la pausa in un punto di interruzione.

Continua

Lascia il punto di interruzione corrente e riprende l'esecuzione del codice normalmente. Questo non influisce su altri breakpoint che non sono ancora stati messi in pausa.

Uso Continua quando il punto di interruzione in pausa corrente non è utile e si desidera che l'esecuzione del codice riprenda normalmente.

Scavalcare

Passa attraverso il codice riga per riga (una riga per clic) finché non viene raggiunta una chiamata di funzione. A questo punto, la chiamata della funzione viene "superata" e non si entra in quella particolare chiamata di funzione.

Uso Scavalcare quando ciò che stai cercando di risolvere è ambito con la funzione corrente, e non hai bisogno di guardare le chiamate di funzioni esterne.

Entra

Simile a Scavalcare, tranne che in questo caso, si naviga verso le chiamate di funzioni esterne andando alla prima riga.

Uso Entra quando sei interessato all'esecuzione linea per linea e alle chiamate di funzioni esterne.

Uscire

Quando entri in una funzione, Uscire continuerà a eseguire il resto del codice delle funzioni, ma non è sottoposto a debug.

Uso Uscire quando non sei interessato al resto della funzione corrente e desideri continuare a eseguire il debug all'esterno.

The Call Stack

Lo stack di chiamate è attivo quando è in pausa in corrispondenza di un punto di interruzione. Il percorso di esecuzione che conduce al punto di interruzione correntemente in pausa viene mostrato nello stack di chiamate, la prima chiamata è la più recente.

Ogni chiamata all'interno della pila contiene:

  • nome della funzione
  • nome del file contenente la funzione
  • la riga di codice in cui esiste la funzione

Fai clic su qualsiasi chiamata all'interno dello stack per navigare fino al suo punto nel codice sorgente con la riga pertinente evidenziata. Per copiare una traccia dello stack negli Appunti, tasto destro del mouse su una chiamata e selezionare Copia traccia dello stack. Nel menu di scelta rapida delle chiamate, puoi anche selezionare Riavvia frame.

Riscrittura delle funzioni durante la pausa in un punto di interruzione

Considerare il caso d'uso in cui il debugger si è fermato a metà strada attraverso una funzione di callback innescata da un gestore di eventi click, e si sta tentando di eseguire il debug perché il recupero del bersaglio non sembra funzionare come previsto. 

Si vede un tentativo di accedere alla proprietà di destinazione come parte del Questo parola chiave, ma si ricorda che si tratta di una parte di proprietà dell'oggetto evento passato come argomento alla funzione di callback. 

Puoi riscrivere la funzione usando Live Edit per verificare che le tue modifiche funzionino, e il nuovo JavaScript viene iniettato nel motore V8.

monitorEvents

Quando stai scrivendo un gestore di eventi per un evento come lo scroll, puoi iniziare usando console.log per vedere come appare l'argomento passato (l'oggetto evento). Un consiglio rapido per farlo è usare il monitorEvents scorciatoia. Incolla il seguente codice nel Pannello della console e poi scorri la pagina:

monitorEvents (window, "ridimensiona");

Si noti che l'oggetto evento viene registrato nella console pronto per l'ispezione.

mettere a punto

Quando si desidera che il debugger si interrompa sulla prima riga di una funzione durante l'esecuzione, è possibile effettuare una delle seguenti operazioni:

  • Aggiungi un punto di interruzione tramite l'interfaccia utente di DevTools.
  • Aggiungi un'istruzione debugger alla funzione.

Un'altra tecnica è quella di eseguire debug (fn) che fa parte dell'API della riga di comando. La funzione accetta la funzione che si desidera eseguire il debug come argomento e si interromperà sulla prima riga dell'esecuzione di quella funzione.

Break on Property Access

Questa tecnica consente di mettere in pausa il debugger quando si accede a una proprietà di un oggetto a cui si è interessati in qualsiasi modo (una lettura o una scrittura). Per interrompere quando una proprietà di un oggetto viene letta o scritta, eseguire quanto segue (tramite il file Pannello della console o Frammenti):

Object.defineProperty (document.body, 'scrollTop', get: function () debugger;, set: function (val) debugger;);

Questo applica un getter e setter al scrollTop proprietà del document.body oggetto. Nel getter e setter personalizzati esiste l'istruzione debugger. Puoi anche usare Object.observe interrompere l'aggiunta di proprietà per un oggetto specificato:

var watchMe = ; Object.observe (watchMe, function () debugger;);

Breakpoint condizionali utilizzando console.log

La parola chiave debugger a parte, per impostare un punto di interruzione tramite DevTools, è possibile fare clic sulla linea di codice che si desidera interrompere all'interno della linea di grondaia. Questo metodo di impostazione di un punto di interruzione ha funzionalità extra: si imposta un punto di interruzione condizionale che istruirà DevTools a mettere in pausa in un punto di interruzione solo se una determinata espressione restituisce true. Ad esempio, è possibile impostare un punto di interruzione condizionale per sospendere solo se esiste un argomento di errore.

Per impostare un punto di interruzione condizionale:

  1. Pulsante destro del mouse all'interno della linea di gronda.
  2. Selezionare Aggiungi punto di interruzione condizionale.
  3. Immettere l'espressione che si desidera che DevTools valuti.
  4. stampa accedere.

È inoltre possibile utilizzare la tecnica del punto di interruzione condizionale per inserire rapidamente a console.log dichiarazione come espressione da valutare. Da console.log valuta a non definito, DevTools non si ferma, ma poiché l'espressione è ancora eseguita, puoi controllare il valore delle variabili in questo modo.

Utilizzando le espressioni di controllo

Quando il debugger viene messo in pausa in un punto di interruzione, è possibile visualizzare il file Pannello della console in modalità cassetto utilizzando il Fuga chiave. Il codice che inserisci viene valutato nello stesso contesto del punto in cui sei in pausa, il che significa che le variabili con ambito saranno accessibili a te.

Un'espressione di controllo è uno strumento per semplificare la tecnica di ispezione regolare (via console.log per esempio) di variabili con scope. Guarda le espressioni è un riquadro all'interno del pannello Sorgenti. Puoi aggiungere o rimuovere le espressioni di controllo usando il Più e Meno pulsanti. Un tipico oggetto da cui guardare è il Questo oggetto; nota come si riferisce a un oggetto finestra globale quando non sei in pausa in un punto di interruzione.

Le espressioni di controllo vengono generalmente aggiornate durante l'esecuzione del codice. In caso contrario, fare clic su ricaricare pulsante.

eccezioni

Considera il seguente script:

funzione a () return b ();  function b () return c ();  function c () console.trace ('The Trace'); ritorno 42;  a ();

Ci sono tre funzioni dichiarate. Funzione un chiama la funzione B, quindi funzione B chiama la funzione c. Lo script avvia la catena con una chiamata alla funzione un. Il console.trace registri di istruzione alla console una traccia di stack dal punto in cui è stato chiamato il metodo. Utilizzando console.trace viene visualizzato l'output di utilizzo console.trace.

Nota che i nomi delle funzioni e le linee in cui sono chiamati sono mostrati nel messaggio di traccia. Puoi fare clic sul numero di riga da portare al suo punto nel codice sorgente tramite il pannello Sorgenti. Questa tecnica funziona anche per i frammenti.

Il debugger offre varie modalità per gestire le eccezioni:

  • Pausa su eccezioni non rilevate.
  • Pausa sulle eccezioni catturate e non catturate.
  • Non mettere in pausa sulle eccezioni.

2. Debugging dall'esterno in

Quando devi eseguire il debug di un sito su cui hai poche informazioni, puoi utilizzare una diversa tecnica di debug. Con questo approccio, ti agganci agli eventi che ritieni possano scatenare e richiedi interruzioni DevTools su tali eventi se e quando si verificano. Esistono due categorie di "fuori> in" punti di ingresso:

  • Modifiche DOM
  • Punti di interruzione del listener di eventi

Break su modifiche DOM

Hai il compito di eseguire il debug di una pagina web, in particolare il DOM. I nodi vengono aggiunti e rimossi durante il ciclo di vita della pagina, ed è necessario ispezionare il codice JavaScript che rende questo accada. Imposta un punto di interruzione DOM con i seguenti passaggi:

  • Fare clic con il tasto destro del mouse su un nodo DOM nel pannello Elementi.
  • Seleziona un punto di interruzione DOM preferito da Interrompi menù contestuale.
  • Mentre sei in pausa in un punto di interruzione, puoi vedere un messaggio che spiega il motivo della pausa del debugger, come mostrato in Reason per la pausa in corrispondenza di un breakpoint.

Ogni volta che imposti un punto di interruzione DOM, puoi facilmente attivarlo e disattivarlo su Punti di interruzione DOM riquadro nel Pannello degli elementi. In questo riquadro, ogni punto di interruzione impostato è elencato ed è possibile interagire con questo riquadro nei seguenti modi:

  • Attiva e disattiva la casella di controllo per abilitare o disabilitare il punto di interruzione.
  • Fare clic sul nome del nodo (che è sottolineato) per spostarsi ad esso nella vista ad albero DOM.
  • Pulsante destro del mouse e selezionare Rimuovi tutti i punti di interruzione DOM per disabilitare e rimuovere tutti i breakpoint DOM.

Modifiche sottostruttura 

Descrizione: Una modifica sottoalbero si verifica quando viene modificato l'albero di un nodo radice (che ha il set di punti di interruzione). Questo può includere l'aggiunta o la rimozione di nodi.

Caso d'uso: Un vuoto div il container è presente nel DOM e una richiesta Ajax si verifica al caricamento della pagina che aggiunge alcuni nuovi nodi al contenitore originale. Aggiungi un punto di interruzione della modifica Sottostruttura sul contenitore per visualizzare il punto esatto nel codice che aggiunge nuovi nodi al DOM.

Esempi di messaggi: In pausa su a Sottostruttura modificata punto di interruzione impostato corpo, perché il suo discendente p è stato rimosso. Oppure: in pausa su a Sottostruttura modificata punto di interruzione impostato div # genitore, perché un nuovo bambino è stato aggiunto a quel nodo.

Modifiche di attributi 

Descrizione: Una modifica di attributo si innesca quando un nome di attributo o valore su un nodo viene aggiunto, rimosso o modificato. Questo include tutti gli attributi, come classedati-*, o stile.

Caso d'uso: Un cambiamento visivo si verifica sulla pagina in un punto temporale apparentemente casuale e lo si riduce a una classe che viene impostata dinamicamente sull'elemento body. Desiderate investigare la causa di questa aggiunta dinamica di classe.

Esempio di messaggio: In pausa su un Attributo Modificato punto di interruzione impostato p.

Rimozione dei nodi 

Descrizione: Un punto di interruzione della rimozione del nodo si attiva nel punto in cui un nodo viene rimosso dal padre contenente il punto di interruzione impostato.

Caso d'uso: Stai costruendo un'app lista di cose da fare e desideri verificare che quando un utente cancella un elemento to-do, viene rimosso anche dal DOM. È possibile impostare un punto di interruzione della rimozione del nodo per garantire che questo comportamento si verifichi.

Esempio di messaggio: In pausa su a Nodo rimosso div # container.

Punti di interruzione del listener di eventi

In DevTools sono disponibili per l'abilitazione numerosi punti di interruzione listener di eventi predefiniti. Questi offrono punti di ingresso nel codice JavaScript che appartiene a una pagina.

Consideri un semplice su bianco pagina. Imposta a clic breakpoint listener di eventi in questa pagina con i passaggi seguenti:

  • Vai a Punti di interruzione del listener di eventi riquadro nel Pannello delle fonti.
  • Apri il Topo Categoria Listener di eventi.
  • Abilita il Clic ascoltatore di eventi.

Ora hai impostato un punto di interruzione. Se fai clic sulla pagina, noti che non succede nulla. Ora esegui il seguente pezzo di codice JavaScript nel Pannello della console.

document.addEventListener ('click', console.log.bind (console))

Quando si imposta un punto di interruzione per lo stesso evento per cui è stato registrato un listener di eventi, il debugger si interrompe prima del punto in cui viene eseguita la richiamata del listener di eventi.

È possibile registrare punti di interruzione per molti tipi di eventi come timer, eventi tattili e altro, elencati nella tabella seguente.

Categoria di eventi Esempi di eventi

Animazione

requestAnimationFrame, cancelAnimationFrame, animationFrameFired

Controllo

ridimensionamento, scorrimento, zoom, messa a fuoco, sfocatura, selezione, modifica, invio, ripristino

appunti

copia, taglia, incolla, soprastampato, prima, pre-pasta

Mutazione DOM

DOMActivate, DOMFocusIn, DOMFocusOut, DOMAttrModified, DOMCharacterDataModified, DOMNodeInserted, DOMNodeInsertedIntoDocument, DOMNodeRemoved, DOMNodeRemovedFromDocument, DOMSubtreeModified, DOMContentLoaded

Dispositivo

deviceorientation, devicemotion

Trascina / rilascia

dragenter, dragover, dragleave, drop

Tastiera

keydown, keyup, keypress, input

Caricare

carica, scarica prima, scarica, interrompi, errore, hashchange, popstate

Topo

fare clic, dblclick, mouse, mouseup, mouseover, mouse mouse, mouseout, rotellina del mouse, ruota

Timer

setTimer, clearTimer, timerFired

Toccare

touchstart, touchmove, touchend, touchcancel

WebGL

webglErrorFired, webglWarningFired


La tecnica di "debugging dall'esterno in" può essere utile quando devi eseguire il debug di un sito Web di terze parti la cui funzionalità è interrotta, o anche quando sei curioso di sapere come funziona qualcosa su una pagina che stai visualizzando.

3. Estensioni

Esistono numerose estensioni di Chrome, molte delle quali migliorano la funzionalità di DevTools. Un elenco in primo piano si trova nella galleria delle estensioni DevTools.

DevTools JavaScript Preprocessing

Per gli autori di DevTools Extension, la funzione di pre-elaborazione di JavaScript è un argomento utile da approfondire. Il preprocessore può intercettare il codice sorgente JavaScript prima che entri nel motore V8, il che significa che il codice sorgente JavaScript può essere modificato tramite DevTools prima che entri nella VM, tutto da un'estensione. 

Oltre alle funzionalità di intercettazione, l'API di pre-elaborazione ha accesso programmatico per il ricaricamento delle fonti di script. Un'estensione può, in qualsiasi momento durante il suo ciclo di vita, ricaricare una sorgente JavaScript senza ricaricare la pagina Web originale.

4. Nodo

Questa sezione comprende alcuni strumenti che offrono un certo livello di integrazione tra Node.js e Chrome DevTools.

Node Inspector

Ci sono due parti per DevTools:

  • Fine frontale: Questo è ciò che usi e interagisci con. È composto da HTML, CSS e JavaScript.
  • Back-end: In caso di ispezione di una pagina in Google Chrome, il back-end si trova all'interno degli interni di Chrome. I messaggi vengono passati avanti e indietro tramite il Remote Debugging Protocol.

Qualsiasi applicazione può implementare la comunicazione tramite il protocollo di debug remoto e consentire agli utenti di eseguire il debug tramite DevTools. Node Inspector è uno di questi strumenti. Dopo l'installazione, puoi eseguire qualsiasi script del nodo usando Node Inspector. Lo strumento avvia un server Web che ospita il front-end DevTools. Questa versione speciale di DevTools non usa il back-end di Chrome, ma piuttosto quello di Node Inspector.

Come puoi vedere in Node Inspector, DevTools è in pausa in un punto di interruzione. Lo stack di chiamate si riferisce alle chiamate eseguite in Node.js. L'unico coinvolgimento del browser qui è per l'interfaccia utente di DevTools.

Node Heapdump

Utilizzare Node Heapdump per acquisire un'istantanea dell'heap V8 in un punto nel tempo nel codice. Lo stato corrente dell'heap V8 viene serializzato e inviato a un file.

Confronta due istantanee di heap per scoprire quali oggetti non vengono raccolti. Questo è utile per rilevare perdite di memoria.

Conclusione

Questo è tutto per questa serie in due parti su una moderna esperienza di debug. Si spera a questo punto che tu sia a tuo agio con la creazione e il debug di JavaScript all'interno di Chrome DevTools. Hai familiarità con i flussi di lavoro che possono aiutare il debugging e sai alcuni trucchi e consigli quando si tratta di un sito di produzione su cui non hai mai lavorato prima. Assicurati di provare alcune delle tecniche che hai imparato qui la prossima volta che devi eseguire il debug.

Grazie per aver letto!