Blog

Näin kirjoitat parempaa koodia linting-, muotoilu- ja analyysityökaluilla

SEP 29, 2020

Ihmiset tekevät joskus virheitä, joita edes code review’t eivät paljasta luotettavasti. Siksi on erittäin suositeltavaa käyttää yhdessä linttaus-, muotoilu- ja analyysityökaluja, jotta koodissa ilmenevät ongelmat voidaan havaita ennen minkäänlaista käyttöönottoa.

Olli Rautiainen

Koodikatselmoinnit ovat erinomaisia huonon suunnittelun paljastamiseen ja ylemmän tason osaamisen jakamiseen, mutta osa bugeista voi jäädä huomaamatta. Tässä blogikirjoituksessa näytämme, miten linttaus-, muotoilu- ja analyysityökaluja yhdistämällä voidaan tunnistaa koodin ongelmia, jotka eivät välttämättä paljastu katselmoinnissa.

Ohjelmointikielet ja suunnittelumallit kehittyvät jatkuvasti, joten myös näitä työkaluja ja niiden määrityksiä tulee ylläpitää aktiivisesti, jotta toiminnallisuus, luettavuus ja syntaksi pysyvät mahdollisimman hyvin ajan tasalla. Kehittäjien ei myöskään tulisi pelätä koodin refaktorointia päivitysten ja korjausten yhteydessä, vaikka koodi toimisi jo oikein, jos he löytävät paremman tavan saavuttaa haluttu lopputulos. Kun linttaus-, muotoilu- ja analyysityökalut otetaan käyttöön hyvin jo kehityksen alusta alkaen, ylläpitovaiheessa tarvitaan huomattavasti vähemmän refaktorointia. Tämä voi säästää merkittävästi aikaa ja arvokkaita resursseja kaikilta osapuolilta.

Käsittelemme kolmea erilaista hyödyllistä työkalutyyppiä, joita voit käyttää koodissasi, kerromme, mitä niiden avulla voi saavuttaa, ja autamme sinua ottamaan ne käyttöön kehityksessä heti. Määritellään kuitenkin ensin, mitä hyvä ja ylläpidettävä koodi tarkoittaa tässä blogikirjoituksessa.

  1. Hyvä koodi tekee sen, mitä sen pitääkin

Ennen kaikkea koodin pitää toimia. Kaikki muu on pitkälti arvotonta, jos koodissa on bugeja. Työkalujen tulisi siis auttaa poistamaan mahdollisia bugeja.

  1. Hyvää koodia on helppo lukea ja muokata

Jos ihmisten on vaikea ymmärtää koodia, sen lukeminen on tuskallisen hidasta ja muutokset johtavat todennäköisesti bugeihin. Työkalujen tulisi siis lisätä yksinkertaisuutta ja selkeyttä.

  1. Hyvä koodi noudattaa yleisiä parhaita käytäntöjä

Saman logiikan voi yleensä toteuttaa monella tavalla, joista osa vaikuttaa yhtä hyviltä. Valintojen suhteen kannattaa kuitenkin olla johdonmukainen, jotta yhden koodikannan lisäksi myös eri projektit pysyvät yhtenäisinä. Tutut ratkaisut parantavat luettavuutta. Työkalujen tulisi siis lisätä yhdenmukaisuutta ja varoittaa huonoista käytännöistä.

Työkalut parempaan koodiin

  • Lintterit

Lintterit

  • Linttereitä, kuten ESLintiä ja Pylintiä, käytetään pääasiassa koodin loogisten ongelmien havaitsemiseen. Ne ovat erityisen tärkeitä tulkattavissa ja väljästi tyypitetyissä kielissä, kuten JavaScriptissä ja Pythonissa, koska niissä ei ole ylimääräistä käännösvaihetta virheiden havaitsemiseksi. Erityisesti JavaScript on hyvin dynaaminen ja omalaatuinen kieli, joka voi johtaa outoon, tahattomaan toimintaan, jos parhaita käytäntöjä ei noudateta. Esimerkiksi ===- ja !==-operaattoreita tulisi suosia ==- ja !=-operaattoreiden sijaan, sillä JavaScriptin tyyppimuunnokset ovat vähintäänkin epäintuitiivisia. Onneksi tähän ja muihin vastaaviin yleisiin käytäntöihin on olemassa ESLint-sääntö.

  • ESLint on myös hyvin laajennettavissa, joten se voidaan ottaa käyttöön ja määrittää varoittamaan lähes kaikesta. Oletussääntöjoukkoa kannattaa todennäköisesti laajentaa lisäosilla kaikille käytetyille frameworkeille, mahdollisesti myös joillekin kirjastoille sekä saavutettavuudelle (esimerkiksi eslint-plugin-jsx-a11y). Koska jokainen projekti on erilainen, säännöt tulisi määrittää projektin versionhallintaan. Mitä lähempänä määritykset ovat suositeltuja oletuksia, sitä helpompi niitä on ylläpitää ja sitä helpompi parhaita käytäntöjä on noudattaa. Hyvä lähtökohta on käyttää kaikkien pakettien uusinta versiota ja niiden suositeltuja sääntöjoukkoja (katso esimerkkimääritys). Jos jokin sääntö ei sovi projektiin, sen voi helposti poistaa käytöstä asettamalla sen arvoksi “off”.

  • Lintterit ovat hyödyllisimpiä, kun ne integroidaan editoriin tarkistamaan koodia kirjoittamisen aikana mahdollisimman nopean palautteen saamiseksi. Mahdolliset virheet korostetaan aina, ja ne voidaan korjata nopeasti. Oletetaan esimerkiksi, että työstän React-sovellusta ja toteutan uutta lomaketta. Ilman ESLintiä ja eslint-plugin-jsx-a11y-lisäosaa on todennäköistä, että lomakkeesta tulee hankala käyttää näppäimistöllä tai sitä on mahdotonta ymmärtää kokonaan ruudunlukijalla. Kukaan ei välttämättä huomaa tätä ennen kuin siitä on aiheutunut todellista haittaa. Hyvin määritetty lintteri ja editori varoittavat kuitenkin heti, jos interaktiiviselta elementiltä puuttuvat näppäimistötapahtumat tai kuvilla ei ole sisältöä kuvaavia alt-attribuutteja.

  • Linttereitä voidaan käyttää myös muotoilun tyylioppaina, kuten suositussa eslint-config-airbnb-määrityksessä. Mielestäni on kuitenkin parempi varmistaa hyvä tyyli automaattisilla muotoilijoilla ja antaa lintterin keskittyä vain loogisiin ongelmiin.

  • Muotoilijat

  • Muotoilijoita, kuten Prettieriä ja Blackia, käytetään varmistamaan projektin yhtenäinen tyyli tulostamalla koodi niiden sääntöjen mukaisessa muodossa. Muotoilijoita käytetään linttereiden rinnalla: lintterit huolehtivat koodin laadusta, muotoilijat muotoilusäännöistä. JavaScriptin ja TypeScriptin lisäksi Prettier voi muotoilla esimerkiksi CSS:ää, Lessiä, SCSS:ää, HTML:ää, JSONia, Markdownia ja YAMLia. Koska koodin muotoilu ei varsinaisesti vaikuta sen toimintaan, sääntöjen tarkka sisältö ei ole yhtä tärkeää kuin se, että yhteiset säännöt ovat käytössä. Siksi parhailla muotoilijoilla on selkeä linja, eivätkä ne tarvitse lainkaan määrityksiä. Useimmista muotoilusäännöistä voidaan väitellä, mutta niiden oletusasetukset on optimoitu luettavuuden kannalta, ja niistä poikkeamiseen on harvoin loogista syytä. Tehokkuuden kannalta muotoiluvaihe kannattaa lisätä pre-commit hookiin, jolloin huonosti muotoiltua koodia ei voi commitoida ja kehittäjä voi kirjoittaa koodin itselleen sopivimmassa muodossa. Muotoilijat voidaan lisäksi integroida editoriin muotoilemaan koodi tiedoston tallennuksen yhteydessä. Hyödyt ovat valtavat: aikaa säästyy huomattavasti, kun tyyliä koskevia päätöksiä ei enää tarvitse tehdä eikä välilyöntejä tai muita valinnaisia merkkejä tarvitse kirjoittaa käsin. Suurten koodikantojen muotoilu onnistuu sekunneissa. Muotoilijat myös helpottavat osallistumista koodikannan kehitykseen, kun projektin muotoilukäytäntöjä ei tarvitse enää opetella.

  • Staattinen koodianalyysi

  • Staattisen koodianalyysin työkalut, kuten SonarQube, analysoivat koodikantaa ja tuottavat siitä mittareita. SonarQube tukee erinomaisesti 27:tä eri ohjelmointikieltä, mukaan lukien CSS:ää ja HTML:ää. Se tunnistaa tehokkaasti vaikeasti havaittavia virheitä, jotka muut työkalut tai ihmiset voivat ohittaa, tutkimalla kaikki mahdolliset suorituspolut. Se varoittaa koodin hajuhaitoista, jotka vaikeuttavat koodin ylläpitoa, vaikka koodi toimisi tarkoitetulla tavalla. Tällaisia ovat esimerkiksi päällekkäinen koodi, liian monimutkainen koodi ja testaamaton koodi. Se varoittaa myös haavoittuvuuksista ja mahdollisesti turvattomasta koodista sekä mittaa koko koodikannan ja uuden tulevan koodin luotettavuutta, tietoturvaa, ylläpidettävyyttä, testikattavuutta ja päällekkäisyyksiä. SonarQubea kannattaa käyttää osana CI/CD-putkea, jotta koodi skannataan aina, kun muutoksia viedään seurattuun haaraan. Lisäksi editoreihin on saatavilla SonarLint-laajennus, jota voi käyttää SonarQuben rinnalla varoittamaan virheistä jo koodia kirjoitettaessa. 

Yhteenveto

Kaikki mainitut työkalut ovat nopeita ja helppoja ottaa käyttöön. Ne tukevat ja noudattavat parhaita käytäntöjä sekä tarjoavat paljon hyötyä pienellä panostuksella: hyvän koodin kirjoittamiseen kuluva aika ja kustannukset pienenevät. Tehokkain tapa käyttää niitä on lintata koodia kirjoitettaessa, formatoida koodi pre-commit-hookissa ja ajaa SonarQube CI/CD-putkessa. Ne toimivat muutosten automaattisina koodikatselmointeina, mikä riittää usein ohjelmiston ylläpitotehtävissä. Kaikki työkalut voi ottaa käyttöön missä tahansa ohjelmiston elinkaaren vaiheessa, mutta niiden käyttö kannattaa aloittaa heti alusta: se on helpompaa ja tehokkaampaa. Kun niitä käytetään hyvien teknisten valintojen, suunnittelun ja säännöllisten päivitysten rinnalla, koodikanta pysyy mahdollisimman helposti ylläpidettävänä nyt ja tulevaisuudessa.

  • Ohjelmistokehitys
  • Sovellushallinta

Subscribe to our newsletter