Staattinen tyyppianalyysi JavaScriptissä. Kokeillaan Facebookin Flow-analysaattoria. JavaScript-suojaus tai suojatun koodin kirjoittaminen JS Analyticsissa ja koodin optimointityökaluissa

Kaikki koodini rivit eivät ole täydellisiä ensimmäisellä kerralla. No, joissain tapauksissa... Joskus... Okei - tuskin koskaan. Totuus on, että käytän huomattavasti enemmän aikaa omien typerien virheideni korjaamiseen kuin haluaisin. Tästä syystä käytän staattisia analysaattoreita melkein jokaisessa kirjoittamassani JavaScript-tiedostossa.

Staattiset analysaattorit tarkastelevat koodiasi ja löytävät siitä virheitä ennen sen suorittamista. Ne suorittavat yksinkertaisia ​​tarkistuksia, kuten valvontasyntaksin (esimerkiksi onko välilyöntien sijasta sarkaimia) ja yleisempiä tarkistuksia, kuten sen, että toiminnot eivät ole liian monimutkaisia. Staattiset analysaattorit etsivät myös virheitä, joita ei löydy testauksen aikana, esimerkiksi == === sijaan.

Suurissa projekteissa ja suurissa ryhmissä työskennellessäsi voisit käyttää hieman apua niiden "yksinkertaisten" vikojen löytämisessä, jotka eivät itse asiassa ole niin yksinkertaisia ​​kuin miltä ne näyttävät.

JSLint, JSHint ja Closure Compiler

JavaScriptin staattisille analysaattoreille on kolme päävaihtoehtoa: JSLint, JSHint ja Closure Compiler.

JSLint oli ensimmäinen staattinen JavaScriptin jäsentäjä. Voit suorittaa sen virallisella verkkosivustolla tai käyttää jotakin lisäosista, jotka voidaan suorittaa paikallisissa tiedostoissa. JSLint löytää monia tärkeitä virheitä, mutta se on erittäin vaikeaa. Tässä on selkeä esimerkki:

Var s = "mystring"; for (var i = 0; i< s.length; i++) { console.log(s.charAt(i)); }

JSLint näyttää kaksi virhettä tässä koodissa:

Odottamaton "++". Siirrä "var"-ilmoitukset funktion yläosaan.

Ensimmäinen ongelma on muuttujan i määritteleminen silmukkaehdoissa. JSLint ei myöskään hyväksy ++-operaattoria silmukan määritelmän lopussa. Hän haluaa koodin näyttävän tältä:

Var s = "mystring"; var i; for (i = 0; i< s.length; i = i + 1) { console.log(s.charAt(i)); }

Arvostan JSLintin tekijöitä, mutta mielestäni tämä on liioittelua. Se osoittautui vaikeaksi myös Anton Kovaleville, joten hän loi JSHint.

JSHint toimii samalla tavalla kuin JSLint, mutta se on kirjoitettu Node.js:n lisäksi ja on siksi joustavampi. JSHint sisältää suuren määrän vaihtoehtoja, joiden avulla voit suorittaa mukautettuja tarkistuksia kirjoittamalla oman raporttigeneraattorin.
Voit ajaa JSHint-verkkosivustolta, mutta useimmissa tapauksissa on parempi asentaa JSHint paikalliseksi komentorivityökaluksi Node.js:n avulla. Kun olet asentanut JSHint, voit suorittaa sen tiedostoissasi seuraavan kaltaisella komennolla:

Jshint test.js

JSHint sisältää myös laajennuksia suosittuihin tekstieditoreihin, joten voit käyttää sitä samalla, kun kirjoitat koodia.

CLOSURE COMILER

Googlen Closure Compiler on täysin erilainen ohjelma. Kuten nimestä voi päätellä, se ei ole vain varmennusohjelma, vaan myös kääntäjä. Se on kirjoitettu Java-kielellä ja perustuu Mozillan Rhino-parseriin. Closure Compiler sisältää yksinkertaisen tilan peruskoodin tarkistuksen suorittamiseen ja monimutkaisemmat tilat, jotka mahdollistavat tiettyjen näkymämääritelmien lisätarkistuksen ja täytäntöönpanon.

Closure Compiler raportoi virheistä JavaScript-koodissa, mutta tuottaa myös JavaScriptin pienennettyjä versioita. Kääntäjä poistaa välilyönnit, kommentit ja käyttämättömät muuttujat ja yksinkertaistaa pitkiä lausekkeita tehden skriptistä mahdollisimman kompaktin.

Google on tehnyt erittäin yksinkertaisen version kääntäjästä saataville verkossa, mutta sinun kannattaa todennäköisesti ladata Closure Compiler ja suorittaa se paikallisesti.

Closure Compiler, tarkistettuaan koodin, tulostaa tiedostoluettelon yhdeksi pienennetyksi tiedostoksi. Voit siis suorittaa sen lataamalla compiler.jar-tiedoston.

Java -jar kääntäjä.jar --js_output_file compress.js --js test1.js --js test2.js

Oikean vahvistusohjelman valinta

Projekteissani yhdistän Closure Compiler ja JSHint. Closure Compiler tekee pienentämisen ja perustarkistuksen, kun taas JSHint tekee monimutkaisemman koodianalyysin. Nämä kaksi ohjelmaa toimivat hyvin yhdessä ja kumpikin kattaa alueita, joita toinen ei voi. Lisäksi voin käyttää JSHint-laajennusominaisuuksia mukautettujen tarkistusten kirjoittamiseen. Yksi yleinen ohjelma, jonka kirjoitin, tarkistaa tietyt toiminnot, joita en tarvitse, kuten sellaisten funktioiden kutsuminen, joita ei pitäisi olla projektissani.

Nyt kun olemme tarkastelleet muutamia ohjelmia tarkistettavaksi, katsotaanpa huonoa koodia. Jokainen näistä kuudesta esimerkistä edustaa koodia, jota ei pitäisi kirjoittaa, ja tilanteita, joissa koodin tarkistajat voivat säästää sinut.

Tässä artikkelissa käytetään JSHintia useimmissa esimerkeissä, mutta Closure Compiler tuottaa yleensä samanlaisia ​​varoituksia.

== vai ===?

JavaScript on dynaamisesti kirjoitettu kieli. Sinun ei tarvitse määrittää tyyppejä, kun kirjoitat koodia, mutta ne ovat olemassa käynnistyksen yhteydessä.

JavaScript tarjoaa kaksi vertailuoperaattoria näiden dynaamisten tyyppien käsittelemiseen: == ja ===. Katsotaanpa tätä esimerkin avulla.

Var n = 123; var s = "123"; if (n == s) ( alert("Muuttujat ovat yhtä suuret"); ) if (n === s) ( alert("Muuttujat ovat identtisiä"); )

Vertailuoperaattori == ovat jäänteitä C-kielestä, jossa JavaScriptin juuret ovat. Sen käyttäminen on lähes aina virhe: arvojen vertaaminen erillään tyypeistä on harvoin sitä, mitä kehittäjä todella haluaa tehdä. Itse asiassa luku "satakaksikymmentäkolme" eroaa rivistä "yksi kaksi kolme". Nämä lausunnot on helppo kirjoittaa väärin ja vielä helpompi lukea väärin. Testaa tätä koodia JSHintilla ja saat seuraavan:

Test.js: rivi 9, sarake 12, odotettiin "===" ja sen sijaan näki "==".

Määrittämättömät muuttujat ja myöhäiset määritelmät

Aloitetaan yksinkertaisella koodilla:

Function test() ( var myVar = "Hei, maailma"; console.log(myvar); )

Näetkö bugin? Teen tämän virheen joka kerta. Suorita tämä koodi ja saat virheilmoituksen:

ReferenceError: myvar ei ole määritetty

Tehdään ongelmasta hieman monimutkaisempi:

Funktiotesti() ( myVar = "Hei, maailma"; console.log(myVar); )

Suorita tämä koodi ja saat seuraavan:

Hei maailma

Tämä toinen esimerkki toimii, mutta sillä on joitain hyvin odottamattomia sivuvaikutuksia. JavaScript-muuttujien ja laajuuden määrittelysäännöt ovat parhaimmillaan hämmentäviä. Ensimmäisessä tapauksessa JSHint raportoi seuraavaa:

Test.js: rivi 3, sarake 17, "myvar" ei ole määritetty.

Toisessa tapauksessa hän raportoi tämän:

Test.js: rivi 2, sarake 5, "myVar" ei ole määritetty. test.js: rivi 3, sarake 17, "myVar" ei ole määritetty.

Ensimmäinen esimerkki auttaa sinua välttämään ajonaikaisen virheen. Sinun ei tarvitse testata sovellustasi - JSHint löytää vian puolestasi. Toinen esimerkki on huonompi, koska testauksen tuloksena et löydä vikaa.

Toisen esimerkin ongelma on salakavalan hienovarainen ja monimutkainen. Muuttuja myVar on nyt kadonnut laajuudestaan ​​ja siirtynyt globaaliin laajuuteen. Tämä tarkoittaa, että se on olemassa ja sen arvo on Hello, World myös testitoiminnon suorittamisen jälkeen. Tätä kutsutaan globaaliksi saasteeksi.

myVar-muuttuja on olemassa kaikille muille funktioille, jotka suoritetaan testifunktion jälkeen. Suorita seuraava koodi, kun olet suorittanut testitoiminnon:

Console.log("myVar: " + myVar);

Saat edelleen Hello, World. myVar-muuttuja roikkuu koko koodisi ympärillä kuin mallipohja, mikä johtaa monimutkaisiin bugeihin, joita etsit koko yön ennen julkaisua, koska unohdit sisällyttää var.

Ja netologian opettaja kirjoitti blogiin sarjan artikkeleita EcmaScript6:sta. Ensimmäisessä osassa tarkastellaan dynaamista koodianalyysiä EcmaScriptissä Iroh.js:n avulla esimerkkien avulla.

Staattinen ja dynaaminen koodianalyysi

Koodianalyysityökalut ovat hyödyllinen työkalu, jonka avulla voit havaita ja tunnistaa koodisi virheet ja omituisuudet. Koodianalyysi voi olla staattista tai dynaamista. Ensimmäisessä tapauksessa lähdekoodi jäsennetään ja analysoidaan suorittamatta sitä. Toisessa tapauksessa suoritus tapahtuu ohjatussa hiekkalaatikkoympäristössä, joka tarjoaa metatietoa sovelluksen elementeistä sen suorituksen aikana.

Johtopäätökset

Iroh.js on tehokas ja toimiva työkalu dynaamiseen koodin analysointiin EcmaScriptissä. Tätä työkalua voidaan käyttää sekä koodin analysointiin, mukaan lukien kutsukaavion rakentamiseen, todellisten tyyppien ja arvojen päättelemiseen muuttujissa ja objekteissa, että lennon aikana tapahtuvaan koodin muokkaamiseen, mukaan lukien tapahtumapohjaiset koodin korjaukset.

Dynaaminen analyysi on melko monimutkainen menetelmä, mutta EcmaScriptille tämä on ainoa tapa analysoida ja korjata koodia, kun otetaan huomioon ankkakirjoitus, isäntäobjektien läsnäolo ja natiivifunktiot, joiden avulla voit muuttaa koodin käyttäytymistä lennossa. teloitus. Iroh.js voi myös käyttää koodia toiminnallisten testien luomiseen ilman, että sitä tarvitsee ensin muokata viemään arvoja.

Se on modulaarinen pakkaaja, joka luo riippuvuuskaavion kaikista JavaScript-sovelluksen moduuleista. Webpack pakkaa moduulit yhdeksi tai useammaksi pieneksi paketiksi selaimen lataamista varten. Lisäksi Webpackia voidaan käyttää tehtävien suorittajana, koska se jäsentää moduulien välisiä riippuvuuksia ja luo resursseja. Löydät lisää Webpackin käyttämisestä projekteissasi.

  • Grunt on tehtävien suorittaja, joka on suunniteltu automatisoimaan toistuvia ja aikaa vieviä tehtäviä. Sen ohjelmistoekosysteemissä on valtava määrä laajennuksia (yli 6000).
  • Gulp ei ole vain yksi tehtävänhallinta, vaan työkalu, jolla on mielenkiintoinen lähestymistapa: se määrittelee JavaScriptin tehtävät funktioiksi, GUl automatisoi myös kipeät tehtävät, tarjoaa laajan ohjelmistoekosysteemin (yli 2700 pluginia) ja se tarjoaa paremman läpinäkyvyyden ja hallinnan käsitellä.
  • Browserify antaa ohjelmistokehittäjille mahdollisuuden käyttää NodeJS-tyylisiä moduuleja selaimissa. Määrität riippuvuudet ja Browserify pakkaa ne kaikki siistiin JS-tiedostoon.
  • Brunch.io on työkalu, jonka pääideoita ovat nopeus ja yksinkertaisuus. Sen mukana tulee yksinkertainen konfigurointi ja yksityiskohtaiset dokumentaatiot, joiden avulla pääset nopeasti käyntiin. Brunch luo automaattisesti kartan JS-tiedostoista ja CSS-tyylisivuista, mikä helpottaa asiakaspuolen virheenkorjausta.
  • Yeoman on universaali työkalu, jota voidaan käyttää melkein minkä tahansa ohjelmointikielen kanssa (JavaScript, Python, C#, Java ja muut). Tätä peruskoodin luontijärjestelmää, jossa on rikas ohjelmistoekosysteemi (yli 6 200 lisäosaa), käytetään verkkosovellusten kehittämiseen. Yeomanin ansiosta voit luoda nopeasti uusia projekteja unohtamatta olemassa olevien ylläpitämistä ja parantamista.
  • IDE:t ja koodieditorit

    • Swagger on joukko sääntöjä ja työkaluja API:iden kuvaamiseen. Työkalu on kielestä riippumaton apuohjelma. Tämä tarkoittaa, että Swagger luo selkeän dokumentaation, joka on sekä ihmisten että koneiden luettavissa ja jonka avulla voit automatisoida API-riippuvaisia ​​prosesseja.
    • JSDoc on joukko työkaluja, jotka luovat automaattisesti monisivuisen tekstidokumentaation (HTML, JSON, XML jne.) JavaScript-lähdekoodin kommenteista. Tämä sovellus voi olla hyödyllinen suurten projektien hallinnassa.
    • jGrouseDoc (jGD) on joustava, avoimen lähdekoodin työkalu, jonka avulla kehittäjät voivat luoda API:ita JavaScript-lähdekoodin kommenteista. jGD ei dokumentoi vain muuttujia ja toimintoja, vaan myös nimiavaruuksia, rajapintoja, paketteja ja joitain muita elementtejä.
    • YUIDoc on NodeJS:llä kirjoitettu sovellus. Se käyttää samanlaista syntaksia kuin Javadocissa ja Doxygenissa. Työkalu tukee myös reaaliaikaisia ​​esikatseluja, kehittynyttä kielitukea ja edistyneitä merkintöjä.
    • Docco on ilmainen dokumentointityökalu, joka on kirjoitettu kirjallisella CoffeeScriptillä. Se luo HTML-dokumentin, joka näyttää kommenttisi koodin välissä. On huomattava, että työkalu tukee JavaScriptin lisäksi myös muita kieliä. Esimerkiksi Python, Ruby, Clojure ja muut.

    Testaustyökalut

    JavaScriptin testaustyökalut on suunniteltu havaitsemaan virheet kehityksen aikana, jotta vältytään käyttäjien virheiltä tulevaisuudessa. Kun käyttäjäsovellusten monimutkaisuus lisääntyy, automaattiset testit eivät ainoastaan ​​paranna sovellusten suorituskykyä, vaan auttavat myös yrityksiä säästämään budjettia.

    • Jasmine on BDD-kehys (Behavior-driven Development), jota käytetään JS-koodin testaamiseen. Sillä ei ole ulkoisia riippuvuuksia, eikä se vaadi DOM:n suorittamista. Jasminella on puhdas ja ymmärrettävä syntaksi, joka tekee testaamisesta nopeampaa ja helpompaa. Kehystä voidaan käyttää myös Python- ja Ruby-koodien testaamiseen.
    • Mocha on toiminnallinen testauskehys, joka käyttää Node.js:ää selaimessa. Se suorittaa testejä peräkkäin tarjotakseen joustavaa ja tarkkaa raportointia, mikä tekee asynkronisista testeistä hauskoja ja helppoja. Mochaa käytetään usein yhdessä Chain kanssa testitulosten tarkistamiseen.
    • PhantomJS:ää käytetään usein etupään testeihin ja yksikkötesteihin. Koska tämä on eräänlainen päätön WebKit, komentosarjat toimivat paljon nopeammin. Se sisältää myös sisäänrakennetun tuen erilaisille verkkostandardeille. Esimerkiksi JSON-, Canvas-, DOM-käsittely-, SVG- ja CSS-valitsimet.
    • Protractor on Node.js:llä kirjoitettu päästä päähän -testauskehys AngularJS- ja Angular-sovellusten testaamiseen. Se rakennettiin WebDriverJS:n päälle ja vahvistaa sovelluksia, kuten loppukäyttäjä, mukautettujen ohjaimien ja sisäänrakennettujen tapahtumien avulla.

    Virheenkorjaustyökalut

    Virheenkorjauskoodi on melko työvoimavaltainen ja aikaa vievä prosessi JavaScript-kehittäjille. Koodin virheenkorjaustyökalut ovat erityisen hyödyllisiä käytettäessä tuhansia koodirivejä. Monet virheenkorjaustyökalut tarjoavat melko tarkkoja tuloksia.

    • JavaScript Debugger on Mozilla Developer Networkin (MDN) työkalu, jota voidaan käyttää erillisenä verkkosovelluksena koodin virheenkorjaukseen eri selaimissa. Firefox tarjoaa paikallisia ja etätoimintoja sekä mahdollisuuden virheenkorjauskoodin Android-laitteessa Firefox for Android -sovelluksella.
    • Chrome Dev Tools on joukko työkaluja, jotka sisältävät useita apuohjelmia JavaScript-koodin virheenkorjaukseen, CSS:n muokkaamiseen ja sovellusten suorituskyvyn testaamiseen.
    • ng-inspector on selainlaajennus, joka on suunniteltu auttamaan kehittäjiä kirjoittamaan, ymmärtämään ja korjaamaan AngularJS-sovelluksia. Apuohjelma sisältää reaaliaikaiset päivitykset, DOM-korostuksen, suoran pääsyn alueisiin, malleihin ja muihin sovelluselementteihin.
    • Augury on Google Chrome -selaimen ja Angular 2 -sovellusten virheenkorjauksen laajennus. Sen avulla Angular 2 -sovelluskehittäjät voivat analysoida suoraan sovelluksen rakennetta ja suorituskykyominaisuuksia, ja se mahdollistaa myös muutosten havaitsemisen.

    Suojaustyökalut

    • Snyk on kaupallinen työkalu JavaScript-, Java- ja Ruby-sovellusten tunnettujen haavoittuvuuksien havaitsemiseen, korjaamiseen ja estämiseen. Palvelulla on oma haavoittuvuustietokanta ja se ottaa tiedot NSP:ltä ja NIST NVD:ltä. Yrityksen tarjoamat korjaustiedostot ja päivitykset antavat kehittäjille mahdollisuuden estää tietoturvariskejä.
    • Node Security Project tarjoaa hyödyllisiä työkaluja riippuvuustarkistukseen ja haavoittuvuuksien havaitsemiseen. NSP käyttää omaa tietokantaa, joka on rakennettu skannaavista npm-moduuleista, sekä tietoja yleisistä tietokannoista, kuten NIST NVD (National Vulnerability Database). Lisäksi NSP tarjoaa integraation GitHub Pull Request- ja CI-ohjelmistoon. Node.js-sovelluksissa on myös reaaliaikainen tarkistus, hälytykset ja suositukset haavoittuvuuksien ratkaisemiseksi.
    • RetireJS on avoimen lähdekoodin riippuvuustarkistus. Sisältää erilaisia ​​komponentteja, kuten komentoriviskannerin, Grunt-laajennuksen, Firefox- ja Chrome-laajennukset, Burp-laajennukset ja OWASP ZAP:n. Retirejs kerää haavoittuvuustietoja NIST NVD:ltä ja muista lähteistä, kuten ongelmanseurantaohjelmista, blogeista ja postituslistoista.
    • Gemnasium on kaupallinen työkalu ilmaisella kokeiluversiolla. Se tukee useita teknologioita ja paketteja, mukaan lukien Ruby, PHP, Bower (JavaScript), Python ja npm (JavaScript). Gemnasium-tietoturvatyökalu sisältää hyödyllisiä ominaisuuksia, kuten automaattiset päivitykset, reaaliaikaiset hälytykset, tietoturvailmoitukset ja Slack-integraatio.
    • OSSIndex tukee useita ekosysteemejä (Java, JavaScript ja .NET/C#) ja monia alustoja, kuten NuGet, npm, Bower, Chocolatey, Maven, Composer, Drupal ja MSI. Se kerää haavoittuvuustietoja National Vulnerability Database (NVD) -tietokannasta ja palautetta. Se käsittelee myös yhteisön jäseniltä saatuja tietoja.

    Analyysi- ja koodin optimointityökalut

    Koodin laadun tarkistamiseksi käytämme yleensä toiminnallista testausta ja yksikkötestausta. On kuitenkin olemassa toinen lähestymistapa, jonka avulla kehittäjät voivat tarkistaa koodin laadun ja sen noudattamisen koodausstandardien kanssa, nimittäin staattinen koodianalyysi.

    Nykyaikaiset ohjelmistot integroivat nyt työkaluja staattisen koodin analysointiin kehityksen aikana varmistaakseen, ettei heikkolaatuista koodia pääse tuotantoon.

    • JSLint on verkkoanalytiikkatyökalu JavaScript-koodin laadun tarkistamiseen. Kun se havaitsee ongelman lähteessä, se palauttaa viestin, jossa kuvataan ongelma ja sen likimääräinen sijainti koodissa. JSLint pystyy analysoimaan tiettyjä tyylikonventioita ja paljastamaan syntaksivirheitä ja rakenteellisia ongelmia.
    • JSHint on joustava, yhteisölähtöinen työkalu vikojen ja mahdollisten ongelmien havaitsemiseen JS-koodissa, ja se on myös JSLint-haarukka. Tämän staattisen koodin analysointityökalun päätarkoitus on auttaa JavaScript-kehittäjiä, jotka työskentelevät monimutkaisten ohjelmien parissa. Se pystyy havaitsemaan syntaksivirheet, implisiittisen tietotyypin muunnoksen tai puuttuvan muuttujan. Se ei kuitenkaan voi määrittää sovelluksesi nopeutta tai oikeellisuutta, eikä se voi määrittää sovelluksesi muistiongelmia. JSHint on JSLintin haarukka.
    • ESLint on avoimen lähdekoodin linteri JSX- ja JavaScript-verkkosovelluksille. Se auttaa sinua havaitsemaan kyseenalaisia ​​malleja tai löytämään koodin, joka ei noudata tiettyjä tyylejä. Näin kehittäjät voivat havaita virheet JS-koodissa suorittamatta sitä, mikä säästää aikaa. Node.js-kielellä kirjoitettu työkalu tarjoaa nopean suoritusajan ja saumattoman asennuksen npm:n kautta.
    • Flow on Facebookin kehittämä staattinen koodiohjain JavaScriptille. Se käyttää staattisia merkintöjä tarkistaakseen koodin virheiden varalta. Tyypit ovat kehittäjien asettamia parametreja, ja Flow tarkistaa ohjelmistosi vaatimustenmukaisuuden.

    Versionhallintatyökalut

    • Viime vuosina Gitistä on tullut laajalti käytetty versionhallintajärjestelmä sekä pienille että suurille projekteille. Tämä ilmainen apuohjelma tarjoaa erinomaisen nopeuden ja tehokkuuden. Sen suosio johtuu sen hajautetusta järjestelmästä ja erityyppisistä ohjaimista sekä esitysalueesta, jossa versioita voidaan tarkastella ja muotoilla juuri ennen sitoumuksen valmistumista.
    • Subversion tai SVN-työkalu on saavuttanut valtavan suosion, ja sitä käytetään edelleen laajalti avoimen lähdekoodin projekteissa ja alustoissa, kuten Python Apache tai Ruby. Tässä CVS:ssä on monia ominaisuuksia, joiden avulla voit hallita erilaisia ​​toimintoja (uudelleennimeäminen, kopiointi, poistaminen jne.), yhdistämistä, tiedostojen lukitsemista ja paljon muuta.

    Pakettien ja riippuvuuden hallintatyökalut

    Luettelo parhaista työkaluista JavaScript-kehitykseen voi jatkua loputtomiin. Tässä artikkelissa näit vain suosittuja ja luotettavia työkaluja, jotka toimivat laadukkaiden tuotteiden perustana.

    Kaikki koodini rivit eivät ole täydellisiä ensimmäisellä kerralla. No, joissain tapauksissa... Joskus... Okei - tuskin koskaan. Totuus on, että käytän huomattavasti enemmän aikaa omien typerien virheideni korjaamiseen kuin haluaisin. Tästä syystä käytän staattisia analysaattoreita melkein jokaisessa kirjoittamassani JavaScript-tiedostossa.

    Staattiset analysaattorit tarkastelevat koodiasi ja löytävät siitä virheitä ennen sen suorittamista. Ne suorittavat yksinkertaisia ​​tarkistuksia, kuten valvontasyntaksin (esimerkiksi onko välilyöntien sijasta sarkaimia) ja yleisempiä tarkistuksia, kuten sen, että toiminnot eivät ole liian monimutkaisia. Staattiset analysaattorit etsivät myös virheitä, joita ei löydy testauksen aikana, esimerkiksi == === sijaan.


    Suurissa projekteissa ja suurissa ryhmissä työskennellessäsi voisit käyttää hieman apua niiden "yksinkertaisten" vikojen löytämisessä, jotka eivät itse asiassa ole niin yksinkertaisia ​​kuin miltä ne näyttävät.


    JSLint, JSHint ja Closure Compiler


    JavaScriptin staattisille analysaattoreille on kolme päävaihtoehtoa: JSLint, JSHint ja Closure Compiler.



    JSLint oli ensimmäinen staattinen JavaScriptin jäsentäjä. Voit suorittaa sen virallisella verkkosivustolla tai käyttää jotakin lisäosista, jotka voidaan suorittaa paikallisissa tiedostoissa. JSLint löytää monia tärkeitä virheitä, mutta se on erittäin vaikeaa. Tässä on selkeä esimerkki:



    var s = "mystring";
    for (var i = 0; i< s.length; i++) {
    console.log(s.charAt(i));
    }

    JSLint näyttää kaksi virhettä tässä koodissa:



    Odottamaton "++".
    Siirrä "var"-ilmoitukset funktion yläosaan.

    Ensimmäinen ongelma on muuttujan i määritteleminen silmukkaehdoissa. JSLint ei myöskään hyväksy ++-operaattoria silmukan määritelmän lopussa. Hän haluaa koodin näyttävän tältä:



    var s = "mystring";
    var i;
    for (i = 0; i< s.length; i = i + 1) {
    console.log(s.charAt(i));
    }

    Arvostan JSLintin tekijöitä, mutta mielestäni tämä on liioittelua. Se osoittautui vaikeaksi myös Anton Kovaleville, joten hän loi JSHint.



    JSHint toimii samalla tavalla kuin JSLint, mutta se on kirjoitettu Node.js:n lisäksi ja on siksi joustavampi. JSHint sisältää suuren määrän vaihtoehtoja, joiden avulla voit suorittaa mukautettuja tarkistuksia kirjoittamalla oman raporttigeneraattorin.

    Voit ajaa JSHint-verkkosivustolta, mutta useimmissa tapauksissa on parempi asentaa JSHint paikalliseksi komentorivityökaluksi Node.js:n avulla. Kun olet asentanut JSHint, voit suorittaa sen tiedostoissasi seuraavan kaltaisella komennolla:



    jshint test.js

    JSHint sisältää myös laajennuksia suosittuihin tekstieditoreihin, joten voit käyttää sitä samalla, kun kirjoitat koodia.


    CLOSURE COMILER


    Googlen Closure Compiler on täysin erilainen ohjelma. Kuten nimestä voi päätellä, se ei ole vain varmennusohjelma, vaan myös kääntäjä. Se on kirjoitettu Java-kielellä ja perustuu Mozillan Rhino-parseriin. Closure Compiler sisältää yksinkertaisen tilan peruskoodin tarkistuksen suorittamiseen ja monimutkaisemmat tilat, jotka mahdollistavat tiettyjen näkymämääritelmien lisätarkistuksen ja täytäntöönpanon.


    Closure Compiler raportoi virheistä JavaScript-koodissa, mutta tuottaa myös JavaScriptin pienennettyjä versioita. Kääntäjä poistaa välilyönnit, kommentit ja käyttämättömät muuttujat ja yksinkertaistaa pitkiä lausekkeita tehden skriptistä mahdollisimman kompaktin.


    Google on tehnyt erittäin yksinkertaisen version kääntäjästä saataville verkossa, mutta sinun kannattaa todennäköisesti ladata Closure Compiler ja suorittaa se paikallisesti.


    Closure Compiler, tarkistettuaan koodin, tulostaa tiedostoluettelon yhdeksi pienennetyksi tiedostoksi. Voit siis suorittaa sen lataamalla compiler.jar-tiedoston.



    java -jar kääntäjä.jar --js_output_file compress.js --js test1.js --js test2.js

    Oikean vahvistusohjelman valinta


    Projekteissani yhdistän Closure Compiler ja JSHint. Closure Compiler tekee pienentämisen ja perustarkistuksen, kun taas JSHint tekee monimutkaisemman koodianalyysin. Nämä kaksi ohjelmaa toimivat hyvin yhdessä ja kumpikin kattaa alueita, joita toinen ei voi. Lisäksi voin käyttää JSHint-laajennusominaisuuksia mukautettujen tarkistusten kirjoittamiseen. Yksi yleinen ohjelma, jonka kirjoitin, tarkistaa tietyt toiminnot, joita en tarvitse, kuten sellaisten funktioiden kutsuminen, joita ei pitäisi olla projektissani.


    Nyt kun olemme tarkastelleet muutamia ohjelmia tarkistettavaksi, katsotaanpa huonoa koodia. Jokainen näistä kuudesta esimerkistä edustaa koodia, jota ei pitäisi kirjoittaa, ja tilanteita, joissa koodin tarkistajat voivat säästää sinut.


    Tässä artikkelissa käytetään JSHintia useimmissa esimerkeissä, mutta Closure Compiler tuottaa yleensä samanlaisia ​​varoituksia.


    == vai ===?


    JavaScript on dynaamisesti kirjoitettu kieli. Sinun ei tarvitse määrittää tyyppejä, kun kirjoitat koodia, mutta ne ovat olemassa käynnistyksen yhteydessä.


    JavaScript tarjoaa kaksi vertailuoperaattoria näiden dynaamisten tyyppien käsittelemiseen: == ja ===. Katsotaanpa tätä esimerkin avulla.



    var n = 123;
    var s = "123";

    jos (n == s) (
    alert("Muuttujat ovat yhtä suuret");
    }

    jos (n === s) (
    alert("Muuttujat ovat identtisiä");
    }

    Vertailuoperaattori == on jäännös C-kielestä, jossa JavaScriptin juuret ovat. Sen käyttäminen on lähes aina virhe: arvojen vertaaminen erillään tyypeistä on harvoin sitä, mitä kehittäjä todella haluaa tehdä. Itse asiassa luku "satakaksikymmentäkolme" eroaa rivistä "yksi kaksi kolme". Nämä lausunnot on helppo kirjoittaa väärin ja vielä helpompi lukea väärin. Testaa tätä koodia JSHintilla ja saat seuraavan:

    test.js: rivi 9, sarake 12, odotettiin "===" ja sen sijaan näki "==".

    Määrittämättömät muuttujat ja myöhäiset määritelmät


    Aloitetaan yksinkertaisella koodilla:



    toimintotesti() (
    var myVar = "Hei, maailma";
    console.log(myvar);
    }

    Näetkö bugin? Teen tämän virheen joka kerta. Suorita tämä koodi ja saat virheilmoituksen:



    ReferenceError: myvar ei ole määritetty

    Tehdään ongelmasta hieman monimutkaisempi:



    toimintotesti() (
    myVar = "Hei, maailma";
    console.log(myVar);
    }

    Suorita tämä koodi ja saat seuraavan:



    Hei maailma

    Tämä toinen esimerkki toimii, mutta sillä on joitain hyvin odottamattomia sivuvaikutuksia. JavaScript-muuttujien ja laajuuden määrittelysäännöt ovat parhaimmillaan hämmentäviä. Ensimmäisessä tapauksessa JSHint raportoi seuraavaa:

    test.js: rivi 3, sarake 17, "myvar" ei ole määritetty.

    Toisessa tapauksessa hän raportoi tämän:



    test.js: rivi 2, sarake 5, "myVar" ei ole määritetty.
    test.js: rivi 3, sarake 17, "myVar" ei ole määritetty.

    Ensimmäinen esimerkki auttaa sinua välttämään ajonaikaisen virheen. Sinun ei tarvitse testata sovellustasi - JSHint löytää vian puolestasi. Toinen esimerkki on huonompi, koska testauksen tuloksena et löydä vikaa.


    Toisen esimerkin ongelma on salakavalan hienovarainen ja monimutkainen. Muuttuja myVar on nyt kadonnut laajuudestaan ​​ja siirtynyt globaaliin laajuuteen. Tämä tarkoittaa, että se on olemassa ja sen arvo on Hello, World myös testitoiminnon suorittamisen jälkeen. Tätä kutsutaan globaaliksi saasteeksi.


    myVar-muuttuja on olemassa kaikille muille funktioille, jotka suoritetaan testifunktion jälkeen. Suorita seuraava koodi, kun olet suorittanut testitoiminnon:



    console.log("myVar: " + myVar);

    Saat edelleen Hello, World. myVar-muuttuja roikkuu koko koodisi ympärillä kuin mallipohja, mikä johtaa monimutkaisiin bugeihin, joita etsit koko yön ennen julkaisua, koska unohdit sisällyttää var.


    Tämä merkintä kulki Full-Text RSS -palvelun kautta - jos tämä on sinun sisältösi ja luet sitä jonkun muun sivustolla, lue UKK osoitteessa http://ift.tt/jcXqJW.


    Turvallisten sovellusten kehittäminen JavaScriptillä on melko monimutkainen tehtävä. Mutta ihan toteutettavissa. Tämän päivän artikkelissa tarkastellaan JavaScriptin ominaisuuksia, jotka aiheuttavat tietoturvaongelmia, ja puhumme tavoista välttää ne.

    Miksi suojatun koodin kirjoittaminen JS:ssä on vaikeaa?

    Joten tässä on 5 syytä, miksi suojatun koodin kirjoittaminen JS:ssä on vaikeaa

    Kääntäjä ei auta

    JavaScript on tulkittu kieli. Tämä tarkoittaa, että kääntäjä ei valita jostain koko ajan, kieltäytyy toimimasta ja pakottaa sinua korjaamaan virheitä ja optimoimaan koodia.

    JavaScriptin dynaaminen olemus

    JavaScript on dynaaminen, heikosti kirjoitettu ja asynkroninen. Ja nämä ovat kaikki merkkejä siitä, että vaikeuksiin joutuminen on helppoa.

    1. Kielityökalut, kuten eval ja kolmannen osapuolen koodin sisällyttäminen script src:n kautta mahdollistavat rivien suorittamisen suoraan suorituksen aikana. Tämän seurauksena on vaikea antaa "staattisia takeita" siitä, että koodi käyttäytyy tietyllä tavalla. Tämä tekee myös dynaamisen analyysin vaikeaksi (katso tieteellinen työ).

    Käyttämällä eval

    2. Heikko kirjoitus Tämä vaikeuttaa vakiintuneiden staattisten analyysitekniikoiden soveltamista, ainakin verrattuna staattisesti kirjoitettuihin kieliin (kuten Java).

    3. Asynkroniset takaisinsoitot, kutsut, jotka JavaScript sallii sellaisten mekanismien kautta, kuten setTimeout ja XMLHttpRequest (sama kuuluisa AJAX), tilastojen mukaan piilottavat kavalimmat virheet.

    Monimutkaiset JS-ominaisuudet

    Mitä ei ole tuotu JavaScriptiin vuosien aikana! Erityisesti siinä on prototyyppejä, ensiluokkaisia ​​toimintoja ja sulkuja. Ne tekevät kielestä entistä dynaamisemman ja suojatun koodin kirjoittamisen vaikeampaa.

    1. Prototyypit. Niiden tarkoitus on, että ohjelmat on kirjoitettu oliolähtöisen lähestymistavan hengessä, mutta ilman luokkien käyttöä. Tällä lähestymistavalla objektit perivät tarvitsemansa ominaisuudet suoraan muilta objektilta (prototyypeiltä). Lisäksi JS:ssä prototyypit voidaan määritellä uudelleen suoraan ajon aikana. Ja jos tämä ohitus tapahtuu, vaikutus koskee välittömästi kaikkia objekteja, jotka perivät ohitetun prototyypin ominaisuudet.

    Kuinka prototyyppejä käsitellään

    Ollakseni rehellinen, on sanottava, että luokat ovat mukana myös uusissa ECMAScript-spesifikaatioissa.

    2. Ensiluokkaiset toiminnot. JS:llä on erittäin joustava objekti- ja funktiomalli. Objektin ominaisuuksia ja niiden arvoja voidaan luoda, muuttaa tai poistaa heti ajon aikana, ja kaikkiin pääsee käsiksi ensiluokkaisten funktioiden kautta.

    3. Sulkemiset. Jos määrität funktion toisen funktion sisällä, ensimmäisellä on pääsy jälkimmäisen funktion muuttujiin ja argumenteihin. Lisäksi nämä muuttujat ovat edelleen olemassa ja pysyvät sisäisen toiminnon käytettävissä - vaikka ulkoinen toiminto, jossa nämä muuttujat on määritelty, on valmis.

    Koska JavaScript on niin joustava ja dynaaminen (katso kohdat 1 ja 3), objektin kaikkien käytettävissä olevien ominaisuuksien joukon määrittäminen staattisen analyysin aikana on vaikea tehtävä. Verkkokehittäjät käyttävät kuitenkin kaikkialla kielen dynaamisia ominaisuuksia, joten niitä ei voida jättää huomiotta koodia analysoitaessa. Muuten mikä on turvallisuuden tae?

    Tiivis vuorovaikutus JavaScriptin ja DOM:n välillä

    Tämä on välttämätöntä verkkosivun "saumattoman" päivityksen varmistamiseksi heti ajon aikana. DOM, sellaisena kuin me sen tunnemme, on standardi, alusta- ja kielineutraali objektimalli HTML- ja XML-dokumenttien hahmontamiseen. DOM:lla on oma API työskennellä hahmonnetun asiakirjan kanssa: dynaamisesti käyttää, siirtää ja päivittää renderöityä asiakirjaa (sen sisältöä, rakennetta ja tyyliä). Muutokset DOM:iin voidaan tehdä dynaamisesti JavaScriptin kautta. Ja nämä muutokset näkyvät välittömästi selaimessa.

    DOM:n ansiosta selaimeen ladatut verkkosivut voidaan päivittää askel askeleelta, kun tietoja ladataan palvelimelta. Tällä mukavuudella on kuitenkin myös haittapuoli: JS:n ja DOM:n välisestä dynaamisesta vuorovaikutuksesta vastaavat koodinpalat ovat erityisen alttiita virheille.

    Yleisimmät virheet verkkosovelluksissa

    Monimutkaiset tapahtumavuorovaikutukset

    JavaScript on tapahtumalähtöinen kieli. Sen avulla kehittäjät voivat rekisteröidä niin sanottuja tapahtumakuuntelijoita DOM-solmuihin. Ja vaikka useimmat tapahtumat käynnistyvät käyttäjän toimesta, jotkin tapahtumat voidaan käynnistää ilman sitä, kuten ajoitetut tapahtumat ja asynkroniset puhelut. Tässä tapauksessa jokainen tapahtuma voi kaikua koko DOM-puussa ja aktivoida useita "kuuntelijoita" kerralla. Joskus tämän kaiken kirjaaminen on melko ei-triviaali tehtävä.

    Miten tapahtumia käsitellään

    Näistä syistä JS-koodia voi olla vaikea ymmärtää, analysoida ja testata. Erityiset apuohjelmat helpottavat verkkokehittäjän elämää ja auttavat sinua kirjoittamaan suojattua koodia.

    Apuohjelmat JS-koodin testaamiseen

    On olemassa apuohjelmia jäsentämiseen (esim. Esprima, Rhino), optimointiin (esim. Google Closure Compiler) ja staattiseen koodianalyysiin yleisiä syntaksivirheitä varten (esim. JSHint).

    Lisäksi on olemassa useita todistettuja kehyksiä, jotka auttavat verkkokehittäjiä peittämään JS-koodin testeillä. Heidän joukossaan:

    • QUnit on suosittu yksikkötestauksen kehys.
    • Jasmine - BDD-kehys (Behavior-driven Development) koodin testaamiseen;
    • Mocha on koodin testauskehys, joka toimii sekä Node.js:ssä että selaimessa;
    • jsTestDriver on kehys, joka muun muassa voi suorittaa joukon testejä useiden selaimien kautta kerralla.

    Lisäksi on olemassa testauskehyksiä, jotka jäljittelevät selaimen käyttäytymistä ja mahdollistavat testitapausten automaattisen suorittamisen. Ne ovat erityisen tärkeitä virheenkorjauksessa koodin osissa, jotka ovat vastuussa JS:n ja DOM:n välisestä vuorovaikutuksesta, ja tarjoavat kätevän infrastruktuurin DOM:n manipuloimiseen.

    Esimerkiksi Selenium, PhantomJS ja SlimerJS tarjoavat API:n, jonka kautta voit käynnistää selaimen ilmentymiä ja olla vuorovaikutuksessa niiden kanssa. API:n kautta voit aktivoida tapahtumia ja käyttää DOM-elementtejä suoraan ajon aikana – eli testata koodia olosuhteissa, jotka ovat mahdollisimman lähellä todellisia. Tietysti huomattava osa työstä on tehtävä manuaalisesti, mutta tämäkin on hyvä apu testauksessa.

    Static Analysis Utilities

    Aiemmin apuohjelmat koodin ongelma-alueiden tunnistamiseen olivat staattisia analysaattoreita. Eli ottaen huomioon kaikki JS:n dynaamiset omituisuudet, he pystyivät tarjoamaan vain rajoitetusti apua. Ne voivat kuitenkin olla hyödyllisiä myös analysoinnissa. Tässä on joitain perusesimerkkejä.

    WARI on staattinen analysaattori, joka tutkii riippuvuuksia JS-funktioiden, CSS-tyylien, HTML-tunnisteiden ja kuvien välillä. Tämän apuohjelman tarkoituksena on löytää käyttämättömät resurssit staattisen analyysin aikana. WARI ei tietenkään pysty selviytymään dynamiikasta.

    JSLint on staattinen koodianalyysityökalu, joka on itse kirjoitettu JavaScriptillä. Se vertaa koodia hyviin käytäntöihin.

    Google Closure Compiler on JS-optimoija, joka kirjoittaa koodin automaattisesti uudelleen tehdäkseen siitä nopeamman ja kompaktimman. Samalla kaikki kommentit ja käyttämättömät koodin osat menevät viemäriin.

    WebScent (katso tieteellinen työ) on edistynyt staattinen analysaattori. Hän lähtee työssään siitä, että asiakkaan JS-koodia (selaimeen ladattua) ei ole tallennettu palvelinpuolelle kokonaisuudessaan, vaan se on hajallaan palvelinkoodin sisällä paloina. Näiden palojen "tuoksua" ei voida helposti havaita ennen kuin niistä on luotu täydellinen asiakaskoodi. WebScent analysoi asiakaskoodia löytääkseen ongelmakohdat palvelinkoodista. Samaan aikaan WebScentin staattisen analysaattorin työ rajoittuu pääasiassa HTML:n, CSS:n ja JS:n sotkujen purkamiseen - jotta voidaan havaita päällekkäinen koodi ja virheet HTML-syntaksissa.

    Dynaamisen analyysin apuohjelmat

    JSNose on apuohjelma, joka yhdistää staattisen ja dynaamisen analyysin. Se analysoi koodin kolmelletoista antipatternille. Seitsemän niistä (mukaan lukien laiska objekti ja pitkä funktio) ovat yhteisiä kaikille ohjelmointikielille, ja loput kuusi (sulkemishajut, liialliset globaalit muuttujat, sisäkkäiset takaisinkutsut ja muut) ovat ominaisia ​​JavaScriptille.

    DOMPletion on automaattinen apuohjelma, joka auttaa verkkokehittäjiä ymmärtämään koodia sitä tarkasteltaessa: selittää, miksi DOM-rakenteet ovat läsnä, suorittaa dynaamisen analyysin ja tarjoaa myös älykkään automaattisen täydennyksen koodille, joka on vuorovaikutuksessa DOM:n kanssa.

    Clematis on kehys, joka auttaa purkamaan monimutkaisia ​​tapahtumavuorovaikutuksia. Clematis vangitsee yksityiskohtaisesti kaikki tapahtumat, jotka käynnistyvät suorituksen aikana, ja visualisoi ne abstraktin käyttäytymismallin muodossa, joka heijastaa komponenttien ja tapahtumien välisiä ajallisia ja syy-seuraus-suhteita.

    Johtopäätökset

    Joten voi olla vaikeaa seurata, mitä tapahtuu suoritettaessa skriptejä JS:ssä, mutta oikeilla työkaluilla voit löytää ja kirjoittaa uudelleen ongelma-alueita jopa hämmentävämmästä koodista. JavaScript ei kuitenkaan pysähdy: siihen ilmestyy uusia ja uusia ominaisuuksia, nyt sitä käytetään usein sovellusten kirjoittamiseen (sekä mobiili- että työpöytäkoneille), ja se löytyy myös yhä enemmän palvelimilta (eikä vain) Node.js:n ansiosta. Tämä tarkoittaa, että bugien pyydystämisen taito on vietävä uudelle tasolle.