Automatická detekce potíží v JavaScriptu s ESLint

27. března 2015

Když píšu JavaScript, zabírají mi spoustu času opravy trapných základních chyb. Často se mi stává, že přejmenuji nějakou proměnnou, aplikaci otestuji, a pak zjistím, že jsem na jednom místě proměnnou přejmenovat zapomněl. Nebo přejmenuji nějaké funkce, a stane se mi to samé. Udělám někde překlep, a pak zase mrhám časem, když klikám v prohlížeči sem a tam.

Pocit mám přitom vždy stejný – jak to, že pořád dělám tento druh chyb? Programuju už víc než patnáct let, přesto se mi to stále stává.

Proto mám v takové oblibě ESLint. Je to stejné, jako když programujete dohromady s někým, kdo dává na takové věci větší pozor, než dokážu já. “Bacha, zase si zapomněl tohle přejmenovat”. “Hele, takhle to rozhodně nedělej”.

ESLint je nástroj, který analyzuje kód a poukazuje na problematická místa, která zjistil. Vyhledává chyby, oblasti, které mohou potenciálně způsobovat potíže. Upozorňuje na nevalný styl při kódování i na stylistické záležitosti. Nejlepší na něm ale je, že se jeho konfigurace dá značně přizpůsobovat, takže pokud nesouhlasíte s něčím, co dělá, můžete mu říct, aby s tím přestal.

Dovolte mi, abych předvedl na příkladu ze skutečného světa, jaké benefity můžete získat, když budete používat ESLint.

Instalace a konfigurace

Než budete moci pokračovat, musíte nejprve nainstalovat ESLint. Podobně jako u mnohých současných JS nástrojů, budete potřebovat nodejs. Jakmile ji budete mít připravenou, spusťte …

npm install -g eslint

Budete tak mít program eslint dostupný z příkazového řádku.

Konkrétní příklad

Abych vysvětlil, jaké benefity poskytuje ESLint, předvedu příklad ze skutečného světa, z kódové báze, na které jsem pracoval. Projdeme si kód a podíváme se, kde a v čem by nám mohl ESLint usnadnit život.

Ukázkový soubor JavaScriptu je vypsaný níže. Nedělejte si starosti s tím, že se zde používá AngularJS – předvedené postupy budete schopni používat pro jakoukoli knihovnu či framework.

var module = angular.module('uploader', []);
/**
* XMLHttpRequest wrapper that supports file upload progress since $http doesn't
*
* Usage similar to $http, returns a promise from the send method
*/
module.service('uploader', ['$q', function($q) {
function readyStateChange(deferred, xhr) {
if(xhr.readyState == 4) {
if(xhr.status == 200) {
deferred.resolve(JSON.parse(xhr.responseText));
}
else {
deferred.reject('HTTP status ' + xhr.status);
}
}
}
function onProgress(deferred, xhr, ev) {
if(ev.lengthComputable) {
deferred.notify({ loaded: ev.loaded, total: ev.total });
}
}
return {
send: function(url, data) {
var fd = new FormData();
for(var k in data) {
fd.append(k, data[k]);
}
var d = $q.defer();
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.onreadystatechange = readyStateChange.bind({}, d, xhr);
xhr.upload.onprogress = onProgress.bind({}, d, xhr);
xhr.send(fd);
return d.promise;
}
};
}]);

Tohle je základní komponenta pro nahrávání souborů na server. Kód je funkční, přesto se podíváme, co se stane, když na něj vypustíme ESLint.

ESLint typicky začíná tím, že zanalyzuje kód a ukáže, co zjistil. Výstup z ESLintu ukázkového modulu vypsaného výše vidíte na obrázku.

javascript_eslint_1

Momentálně výstup obsahuje chyby, jaké by se v modulech vyskytovat neměly, například že nejsou definované ani Angular, ani XMLHttpRequest.

Proč si ESLint stěžuje na XMLHttpRequest? To by nepochybně dělat neměl, protože XMLHttpRequest je standard. Sice to tak je, ale XMLHttpRequest je standardem pouze v prohlížeči. Jiná prostředí, jako je NodeJS, ho možná nemají. Proto bude naším prvním krokem sdělit ESLint, že kód hodláme spouštět v prohlížeči.

Uděláme to tak, že vytvoříme konfigurační soubor s názvem .eslintrc, s jehož pomocí řekneme ESLint, co má dělat. Níže vidíte první verzi našeho souboru .eslintrc.

{
"env": {
"browser": 1
}
}

ESLint lze konfigurovat pomocí JSON. Zde mu říkáme, že prostředím je prohlížeč. Prostředí browser způsobí, že ESLint přestane vydávat za chyby věci, jako jsou XMLHttpRequest nebo window. Pokud byste chtěli příklad vyzkoušet v NodeJS, zařaďte navíc „node“: 1, což dělá totéž s výjimkou Node-builtins.

Spusťme eslint ještě jednou a podívejme se, jaký teď dostaneme výstup.

javascript_eslint_2

Chyby o prostředí prohlížeče jsou pryč, jedna, kterou tu ale rozhodně nechceme, tu stále je: není definovaný ‘angular’. V typické aplikaci bychom zařadili knihovny jako je Angular v podobě značek script, což je učiní dostupnými globálně. Chceme-li o tomhle informovat ESLint, je třeba do konfiguračního souboru přidat dodatečné volby:

{
"env": {
"browser": 1
},
"globals": {
"angular": 1
}
}

Pole globals konfiguruje globální proměnné. V tomto případě definujeme angular, ale pokud byste používali jQuery nebo Backbone nebo Underscore nebo cokoli jiného, stejným způsobem byste přidali $ nebo Backbone nebo _.

Spusťte eslint znovu a vidíte, ta chyba je pryč.

javascript_eslint_3

Ještě ale pořád zbývá několik věcí, které chci změnit. U řetězců dávám přednost apostrofům, takže přidám pravidlo, kterým to napravím.

{
"env": {
"browser": 1
},
"globals": {
"angular": 1
},
"rules": {
"quotes": [2, "single"]
}
}

Vlastnost rules konfiguruje pravidla ESLint. Pravidlo quotes určuje, zda bude ESLint hlásit jako chybu styl apostrofů a který styl je povolený. Číslo 2 znamená, že se bude hlásit chyba. Pokud uvedete číslo 1, bude se hlásit upozornění (warning), které se ve výstupu prezentuje odlišně (žlutě). „single“ říká ESLintu, že povoluji jen apostrofy.

javascript_eslint_warning

Kódová báze tohoto příkladu ani nepoužívá striktní mód, ani nepožaduje trojitá rovnítka, takže dodám i tato pravidla.

Abyste viděli, která pravidla máte konfigurovat, přidal jsem to do obrázku předchozího výstupu.

javascript_eslint_4

Z něho vidíme, že pro příkaz “use strict” se pravidlo jmenuje “strict”, pro === se pravidlo jmenuje “eqeqeq”. Tato dvě pravidla teď přidáme do konfigurace:

{
"env": {
"browser": 1
},
"globals": {
"angular": 1
},
"rules": {
"quotes": [2, "single"],
"eqeqeq": 0,
"strict": 0
}
}

javascript_eslint_5
Když se nějaké pravidlo nastaví na 0, bude ho ESLint ignorovat.

Zbývající chyby se už opraví snadno. Z řádku 35 odstraníme koncové mezery a odstraníme také prázdný řádek na konci souboru.

Chytání chyb

Ukázkový kód nyní projde skrz ESLint bez chyb. Zanesme do kódu několik změn, abychom upozornili na další zajímavé možnosti.

Pamatujete se, jak jsem výše řekl, že se mi stává, že přejmenuju nějakou proměnnou a někde ji přejmenovat zapomenu? Podívejme se, jak se s tím ESLint vypořádá. Přejmenuji xhr na request…

var request = new XMLHttpRequest();
request.open('POST', url, true);
request.onreadystatechange = readyStateChange.bind({}, d, xhr);
request.upload.onprogress = onProgress.bind({}, d, xhr);
request.send(fd);

Vidíte na první pohled, kde je chyba? Ponechal jsem v kódu dva výskyty xhr. Podívejme se, co se stane, když spustíme ESLint na takto upravený kód.

javascript_eslint_6

ESLint vypíchne dvě nedefinované proměnné, které v tomto případě vznikly nekompletním přejmenováním původní proměnné. Nyní chyby tohoto druhu zachytíme ihned, nemusíme trávit mládí klikáním v prohlížeči semhle tamhle.

Pro ještě větší zábavu můžeme udělat nějakou syntaktickou chybu:

javascript_eslint_7

To byly jen dvě krátké ukázky toho, co všechno dokáže ESLint polapit. Seznam zabudovaných pravidel je velmi dlouhý, dokonce můžete psát svá vlastní pravidla nebo instalovat pluginy.

Doporučení

ESLint se může stát velmi cenným nástrojem, ale podobně jako u jakéhokoli jiného nástroje, má-li přinášet znatelné benefity, je třeba ho používat řádně.

Tady máte pět mých doporučení, abyste mohli z ESLint vyždímat co nejvíc:

  1. Podívejte se do dokumentace, kde najdete další informace.
  2. Spusťte ho na svůj projekt a nakonfigurujte tak, aby sedl jako ulitý vašemu stylu kódování.
  3. Nainstalujte si dodatečné pluginy pro knihovny, které používáte, aby byl pro vás ESLint ještě prospěšnější.
  4. Automatizujte ESLint, abyste ho nikdy neopomněli spustit,
  5. Získejte okamžitou zpětnou vazbu tím, že ho budete integrovat do svého editoru nebo integrovaného vývojového rozhraní (IDE).

Abych vám tyto věci opravdu usnadnil, vytvořil jsem průvodce složeného z pěti kroků. Poté, co se přihlásíte, získáte ho z mého webu.

ESLint poskytuje základní záchrannou síť. Zachytí mnoho chyb, které se snadno udělají, a je velmi prospěšný, když pracujete v týmu a potřebujete si vynutit jistý styl kódování. Chcete-li ale mít pevnější záchrannou síť, měli byste investovat do unit testů. To je však téma na někdy jindy.

Kdo je Jani Hartikainen

Jani Hartikainen strávil přes deset let budováním webových aplikací. Mezi jeho klienty patří firmy jako Nokia a žhavé supertajné startupy. Když ani neprogramuje, ani nehraje hry, píše na svém webu o JavaScriptu a vysoce kvalitním kódu.

Původní článek: Detect JavaScript Problems Automatically With ESlint

Zdrojové kódy jsou pod licencí MIT.

  • Translation: RNDr. Jan Pokorný
  • Language and expert collaboration: Marek Machač
Štítky: javascript

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *