Noi, ca dezvoltatori, scriem coduri. Acum nu doar scriem, ci verificăm și dacă codul scris funcționează. Petrăm mult timp și facem mult efort, asigurându-ne că programele noastre fac ceea ce ar trebui să facă. Acest proces de depanare este de multe ori dureros. Mai ales dacă nu folosim instrumentele potrivite. Pentru a ajuta la această problemă, articolul de astăzi introduce Deb.js, o mică bibliotecă JavaScript care vă ajută să depanați în interiorul browserului.
Să începem prin crearea unei pagini simple cu interacțiunea cu JavaScript. Vom crea un formular cu două câmpuri și un buton. Odată ce utilizatorul face clic pe buton, vom colecta datele și vom emite un mesaj în consola. Aici este marcajul paginii:
Pentru a simplifica exemplul, vom folosi jQuery pentru selectarea și evenimentele DOM. Vom înfășura funcționalitatea în următorul modul:
var Module = collectData: funcția (cb) var nume = $ ('[nume = "nume"]). var adresa = $ ('[nume = "adresa"]') val (); dacă (nume! = "&& adresa! =") cb (null, nume: nume, adresa: adresa); altceva cb (msg: 'Missing data'); , eroare: funcția (err) $ ('[data-element = "output"].) html (err.msg); , succes: funcția (date) $ ('[data-element = "output"].) html (' Hello '+ data.name +'! ');
collectData
funcția obține valoarea din câmpuri și verifică dacă utilizatorul a tastat ceva. Dacă nu, atunci se declanșează apelul cu un obiect care conține un mesaj de eroare scurt. Dacă totul este OK, acesta răspunde nul
ca primul parametru și un alt obiect ca cel de-al doilea, care ține datele. Dezvoltatorul care utilizează modulul trebuie să verifice dacă există un obiect de eroare trecut. Dacă nu, atunci începeți să utilizați al doilea argument primit. De exemplu:
$ ('[value = "register"]') (functie () err); altfel Module.success (data);););
Deci, verificăm dacă greși
parametrul este un obiect și dacă da, atunci vom afișa mesajul. Dacă analizăm cu atenție codul, vom observa problema, dar să verificăm cum funcționează totul:
Când nu există date, scriptul funcționează așa cum era de așteptat. Există Date lipsa
text afișat sub formular. Cu toate acestea, dacă adăugăm ceva în câmpuri și apăsăm butonul, obținem: Uncaught TypeError: Nu se poate citi proprietatea 'msg' de null
, mesaj. Acum, haideți să vâsem bug-ul și să-l scoatem.
Google Chrome are instrumente minunate pentru rezolvarea unor astfel de probleme. Putem face clic pe eroarea aruncată și vom vedea următoarea stivă. Am putea ajunge chiar la locul exact în care sa produs eroarea.
Se pare ca eroare
metoda modulului nostru primește ceva care este nul
. Și, desigur, nul
nu are o proprietate numită msg
. De aceea browserul aruncă eroarea. Există un singur loc în care eroare
funcția este invocată. Să punem o pauză și să vedem ce se întâmplă:
Se pare că am primit dreptul date
obiect și eroare
este egal cu nul
, care este comportamentul corect. Deci, problema ar trebui să fie undeva în dacă
clauză. Să adăugăm a console.log
și să vedem dacă mergem în direcția cea bună:
Module.collectData (funcția (err, date) console.log (typeof err); dacă (typeof err === 'obiect') Module.error (err); );
Și într-adevăr, tip eroare
se intoarce obiect
. De aceea, noi întotdeauna prezentăm o eroare.
Și voila, am găsit problema. Trebuie doar să schimbăm dacă
declarație la dacă (err)
și experimentul nostru mic va funcționa conform așteptărilor.
Cu toate acestea, această abordare poate fi uneori dificilă, deci luați în considerare următorii indicatori:
Oprirea programului în timpul executării și verificarea stării acestuia este inutilă, dar Chrome nu are cum să știe ce vrem să vedem. Așa cum sa întâmplat în cazul nostru, trebuie să verificăm din nou dacă
clauză. Nu ar fi mai bine dacă am avea un instrument direct accesibil din codul nostru? O bibliotecă care aduce informații similare, cum ar fi depanatorul, dar trăiește în interiorul consolei? Ei bine, Deb.js ar putea fi răspunsul la această întrebare.
Deb.js este o bucată mică de cod JavaScript, 1.5 kilobytes minified, care trimite informații la consola. Ar putea fi atașat fiecărei funcții și tipărite:
Să vedem cum arată exemplul nostru, atunci când folosim Deb.js:
Vom vedea din nou argumentele transmise exact și urmărirea stivei. Cu toate acestea, observați schimbarea în consolă. Lucrăm la codul nostru, găsim unde poate fi problema și adăugați .deb ()
după definiția funcției. Observați că tipul de greși
este amplasat frumos în interiorul funcției. Deci, nu trebuie să o căutăm. Rezultatul este, de asemenea, grupat și pictat. Fiecare funcție pe care dorim să o depanăm va fi imprimată cu o culoare diferită. Să rezolvăm acum bug-ul nostru și să punem altul deb ()
pentru a vedea cum arată.
Acum avem două funcții. Am putea distinge cu ușurință între ele pentru că sunt în culori diferite. Vom vedea timpul de intrare, ieșire și execuție. Dacă există console.log
declarații, le vom vedea în interiorul funcțiilor în care apar. Există chiar și o opțiune pentru a lăsa o descriere pentru o mai bună recunoaștere a funcțiilor.
Observați că am folosit-o debc
si nu debutantă
. Este aceeași funcție, dar producția se prăbușește. Dacă începeți să utilizați Deb.js, veți afla foarte curând că nu doriți întotdeauna să vedeți totul.
Ideea inițială a venit din blogul lui Remy Sharp despre găsirea unde console.log
are loc. El a sugerat că putem crea o eroare nouă și să obținem următoarea stivă:
[], pentru orice functie (metoda) var old = consola [metoda]; consolă [method] = function () var stack = n /); // Chrome include o singură linie "Eroare", FF nu. dacă (stack [0] .indexOf ('Error') === 0) stack = stack.slice arge = [] .slice.apply (argumente) .concat ([stack [1] .trim ()]); return old.apply (consola, args);;)
Postarea inițială poate fi găsită pe blogul lui Remy. Acest lucru este util în special dacă ne dezvoltăm într-un mediu Node.js.
Deci, cu următoarea stivă în mână, am avut cumva nevoie să injectez codul la începutul și la sfârșitul funcției. Atunci când modelul folosit în proprietățile calculate ale lui Ember mi-a apărut în cap. Este o modalitate frumoasă de a modifica originalul Function.prototype
. De exemplu:
Function.prototype.awesome = funcția () var original = aceasta; funcția return () console.log ('înainte'); var args = Array.prototype.slice.call (argumente, 0); var res = original.apply (aceasta, args); console.log ( 'după'); return res; var doSomething = funcție (valoare) valoarea returnată * 2; .minunat(); console.log (doSomething (42));
acest
cuvântul cheie din patch-ul nostru, indică funcția inițială. Putem să o executăm mai târziu, ceea ce este exact ceea ce am avut nevoie, pentru că am putea urmări timpul înainte și după execuție. În același timp, ne întoarcem propria funcție care acționează ca proxy. Noi am folosit .aplicați (acest lucru, args)
pentru a păstra contextul și argumentele transmise. Și, din fericire, la sfatul lui Remy, putem obține și o urmă de stivă.
Restul implementării Deb.js este doar o decorare. Unele browsere acceptă console.group
și console.groupEnd
care ajută foarte mult la aspectul vizual al exploatării. Chrome chiar ne dă posibilitatea de a picta informațiile imprimate în culori diferite.
Cred în folosirea instrumentelor și instrumentelor minunate. Browserele sunt instrumente inteligente dezvoltate de oameni inteligenți, dar uneori avem nevoie de ceva mai mult. Deb.js a venit ca un utilitar mic și a ajutat cu succes la îmbunătățirea fluxului meu de depanare. Este, desigur, open source. Simțiți-vă liber să raportați probleme sau să faceți cereri de tragere.
Vă mulțumim pentru lectură.