Używamy cookies, żeby zwiększyć Twoje doświadczenia na stronie
CodeWorlds
Powrót do kolekcji
Przewodnik13 min czytania

React Doctor, ocena zdrowia kodu React

React Doctor skanuje projekt React i zwraca wynik od zera do stu wraz z listą problemów. Jak liczy ocenę, co wyłapuje, wpięcie w proces i granice narzędzia.

React Doctor, czyli jedno polecenie i ocena projektu

React Doctor skanuje projekt React i zwraca ocenę od zera do stu wraz z listą konkretnych problemów. Nie wymaga instalacji ani konfiguracji, bo uruchamia się jednym poleceniem i sam wykrywa użyty framework oraz wersję biblioteki.

Code
Bash
npx -y react-doctor@latest .

Narzędzie pochodzi od zespołu znanego z biblioteki przyspieszającej renderowanie w Reakcie, a kod jest publiczny. Licencja to jednak zmodyfikowany wariant permisywnej, z dwoma wyłączeniami wymagającymi pisemnej zgody: użycia kodu jako danych do trenowania albo oceny modeli oraz odsprzedaży narzędzia jako płatnej usługi hostowanej. Do zwykłego użycia w projekcie i w procesie budowania nie ma to znaczenia, natomiast określenie „otwarte" bez zastrzeżeń byłoby tu nieścisłe. Pod spodem działa szybki analizator napisany w Ruście oraz osobne przejście wykrywające kod, do którego nic nie prowadzi.

Deterministyczne, czyli powtarzalne

To rozróżnienie warto postawić na początku, bo narzędzia analizujące kod dzielą się dziś na dwie rodziny, a materiały o nich regularnie je mieszają.

Narzędzia oparte o modele językowe czytają kod i formułują uwagi własnymi słowami. Widzą kontekst, potrafią ocenić sens rozwiązania i przy każdym uruchomieniu mogą powiedzieć coś innego.

To narzędzie należy do drugiej rodziny. Sprawdza ustalony zestaw reguł, więc ten sam kod zawsze daje ten sam wynik. Nie oceni, czy komponent ma sens, natomiast powie z pewnością, że w siedemnastu miejscach jest efekt uboczny, który da się zastąpić wyliczeniem podczas renderowania.

Konsekwencja jest praktyczna. Ocena z tego narzędzia nadaje się na bramkę w procesie budowania, bo jest powtarzalna i nie zablokuje wdrożenia dlatego, że model miał gorszy dzień. Ocena z narzędzia opartego o model językowy nadaje się do przeglądu, gdzie liczy się zrozumienie zamiaru.

Te dwa podejścia nie konkurują ze sobą, tylko pokrywają różne warstwy. Sensowny układ obejmuje oba: automat deterministyczny w procesie budowania i przegląd kontekstowy przy zgłoszeniach scalenia.

Zastrzeżenie dotyczy wyłącznie samej liczby na końcu. Znaleziska powstają lokalnie i są powtarzalne, natomiast punktacja przychodzi z usługi dostawcy, o czym za chwilę.

Skąd bierze się ocena

Ta liczba nie powstaje na Twojej maszynie i to jest rzecz, którą trzeba wiedzieć przed wpięciem narzędzia gdziekolwiek. Skan jest lokalny, natomiast lista znalezisk idzie po sieci do usługi dostawcy, a ta odsyła wynik, etykietę słowną i przypisanie reguł do czterech poziomów pilności oznaczonych od P0 do P3.

Wysyłany pakiet obejmuje same znaleziska po oczyszczeniu, czyli identyfikator reguły, komunikat i ścieżkę pliku z wymazanymi wrażliwymi fragmentami, oraz metadane przebiegu: repozytorium, skrót zmiany, framework, wersję Reacta, liczbę plików źródłowych i gałąź domyślną. Kod źródłowy w tym pakiecie nie jedzie.

Konsekwencje są dwie i obie praktyczne. Bez dostępu do sieci ocena po prostu nie powstaje: narzędzie wypisuje ostrzeżenie, że usługa jest nieosiągalna, a lista problemów zostaje nietknięta. Jeśli tego ruchu nie chcesz, wyłącza go jeden przełącznik, który przy okazji odcina odsyłacz do udostępniania wyniku i zgłaszanie awarii.

Code
Bash
npx react-doctor@latest --no-score

Druga konsekwencja dotyczy porównywania w czasie. Same znaleziska są powtarzalne, bo pochodzą z ustalonego zestawu reguł uruchamianego lokalnie, natomiast przelicznik na punkty stoi po stronie dostawcy i może się zmienić bez zmiany wersji pakietu. Wynik ma więc sens jako szereg pomiarów robionych tą samą wersją w krótkim odstępie, a nie jako liczba porównywana z zeszłym kwartałem.

Kolejność poprawiania bierz z odpowiedzi usługi, a nie z licznika wystąpień. Przypisanie reguły do poziomu od P0 do P3 mówi, co jest pilne, a liczba miejsc, w których reguła została naruszona, mówi tylko, ile pracy to zajmie.

Sama liczba jest zresztą mniej ważna niż jej kierunek. Wynik siedemdziesiąt cztery nic nie mówi w oderwaniu od kontekstu, a wynik, który spadł z osiemdziesięciu do siedemdziesięciu czterech po ostatnim tygodniu pracy, mówi bardzo dużo.

Co wyłapuje

Zestaw reguł jest nastawiony na Reacta, a nie na ogólne zasady pisania kodu, i to jest jego główna wartość wobec zwykłego analizatora.

Zbędne efekty uboczne to najczęstsze znalezisko. Wartość wyliczana z właściwości i stanu nie potrzebuje efektu ani osobnego stanu, tylko zwykłego wyrażenia podczas renderowania. Ten wzorzec powtarza się w niemal każdym projekcie i jest źródłem podwójnych renderowań oraz trudnych do wytropienia błędów.

Przekazywanie właściwości przez wiele poziomów w dół to drugie. Wartość podawana przez pięć komponentów, z których żaden jej nie używa, wskazuje na brakującą warstwę kontekstu albo na zły podział komponentów.

Martwy kod to trzecie i zwykle najbardziej zaskakujące. Komponenty, funkcje pomocnicze i całe pliki, do których nic nie prowadzi, zostają w projekcie po refaktoryzacji i nikt ich nie usuwa, bo nikt nie wie, że są niepotrzebne.

Dalej dochodzą importy zaciągające całą bibliotekę zamiast jednej funkcji, dostępność, gdzie brakująca etykieta albo zły element semantyczny wychodzą wprost z kodu, oraz typowe pułapki bezpieczeństwa, jak wstawianie surowego kodu strony z niesprawdzonego źródła.

Osobno stoi sprawdzenie zależności pod kątem podejrzanych pakietów. Robi je zewnętrzna usługa, więc wymaga sieci i wyłącza się własnym przełącznikiem --no-supply-chain, co ma znaczenie przy budowaniu w środowisku odciętym od internetu.

Pełną listę reguł da się obejrzeć przed pierwszym uruchomieniem na projekcie, a pojedynczą regułę wyjaśnić albo wyciszyć, jeśli nie pasuje do przyjętych ustaleń.

Code
Bash
npx react-doctor@latest rules list
npx react-doctor@latest rules explain <nazwa-reguly>
npx react-doctor@latest rules disable <nazwa-reguly>

Warto zajrzeć do wyjaśnienia, zanim wyłączysz regułę. Część uwag wygląda na czepialstwo do momentu, w którym widać, jaki błąd ma wyłapywać, a wtedy decyzja bywa odwrotna. Kategorię da się też ustawić hurtem, co jest wygodniejsze niż wyłączanie reguł po jednej.

Wpięcie w proces

Uruchomienie ręczne jest dobre na start i słabe jako nawyk, bo nikt nie pamięta o uruchamianiu czegokolwiek.

Właściwym miejscem jest proces budowania przy zgłoszeniu scalenia. Narzędzie potrafi przeskanować wyłącznie zmienione pliki i dopisać uwagi jako komentarze przy konkretnych liniach, co jest znacznie skuteczniejsze niż raport, do którego trzeba wejść osobno.

Zakres skanowania ustawia się jednym przełącznikiem, a wariant porównujący z gałęzią bazową zgłasza wyłącznie to, co doszło w tej zmianie.

Code
Bash
npx react-doctor@latest --scope changed --base origin/main --blocking error

Drugi przełącznik decyduje o tym, kiedy proces budowania ma się wywrócić. Wartość domyślna przerywa przy błędach, wariant ostrzegawczy przerywa także przy uwagach niższej wagi, a wyłączenie blokowania pozwala zbierać dane przez pierwsze tygodnie bez zatrzymywania nikomu pracy. Ten ostatni wariant jest właściwym startem w istniejącym projekcie.

Przy istniejącym projekcie warto ustawić bramkę względem stanu obecnego, a nie względem ideału. Zapisz dzisiejszy wynik jako punkt odniesienia i blokuj wyłącznie zmiany, które go obniżają. Bramka wymagająca dziewięćdziesięciu punktów w projekcie mającym sześćdziesiąt cztery zostanie wyłączona w ciągu tygodnia i przestanie cokolwiek chronić.

Sensowna kolejność wdrożenia wygląda tak. Najpierw uruchom raz i przejrzyj listę, bo część reguł może nie pasować do Twojego projektu. Potem wyłącz te, których świadomie nie zamierzacie stosować, bo szum obniża wartość reszty. Dopiero potem włącz bramkę na poziomie obecnego wyniku i podnoś go stopniowo.

Osobne miejsce to sprawdzenie przed zatwierdzeniem zmiany, gdzie liczy się wyłącznie czas wykonania. Skanowanie samych plików przygotowanych do zatwierdzenia, z narzuconym budżetem czasu, mieści się w kilku sekundach.

Code
Bash
npx react-doctor@latest --staged --max-duration 15

Budżet czasu jest tu ważniejszy, niż się wydaje. Sprawdzenie trwające pół minuty zostanie obejściem przy pierwszym pośpiechu, a raz obchodzone przestaje istnieć. Lepszy jest wynik częściowy w piętnaście sekund niż pełny, którego nikt nie doczeka.

Co to kosztuje

Cennik łatwo przeoczyć, bo narzędzie uruchamia się jednym poleceniem i nie prosi o konto. Dostawca dzieli użycie na dwa przypadki: darmowe prywatne, obejmujące nieograniczone uruchomienia wiersza poleceń i akcję w GitHubie, oraz plan zespołowy za trzydzieści dolarów miesięcznie, który obejmuje użycie komercyjne jednego i drugiego.

Trzeci wariant, przeznaczony dla dużych wdrożeń, wyceniany jest indywidualnie i dokłada wsparcie priorytetowe, pomoc przy wdrożeniu, wcześniejszy dostęp do nowych reguł oraz reguły pisane pod konkretny projekt.

Licencja i cennik mówią przy tym o czym innym i warto ich nie mylić. Licencja opisuje, co wolno zrobić z kodem narzędzia, a cennik to, za co dostawca oczekuje zapłaty przy użyciu firmowym. Przed wpięciem skanu w proces budowania w pracy to jest pytanie do rozstrzygnięcia, a nie szczegół do odłożenia.

React Doctor kontra alternatywy

RozwiązanieMocna stronaSłabośćKiedy wybrać
React DoctorZero konfiguracji, reguły pod Reacta, powtarzalny wynikNie ocenia sensu rozwiązaniaSzybka ocena stanu projektu i bramka w procesie
Klasyczny analizator koduPełna konfiguracja, ogromny wybór regułKonfiguracja zajmuje dniZespół z ustalonymi zasadami
QodoPrzegląd zgłoszeń, generowanie testówWymaga konta i limitówPrzegląd zmian przed scaleniem
GreptileKontekst całego repozytoriumBrak wariantu do wdrożenia u siebieDuże repozytorium z wieloma zależnościami

Pierwszy wiersz wygrywa tam, gdzie liczy się czas do pierwszego wyniku. Jedno polecenie i ocena po minucie to zupełnie inna sytuacja niż dzień konfigurowania reguł, zwłaszcza gdy chcesz tylko sprawdzić, w jakim stanie jest odziedziczony projekt.

Drugi wiersz nie jest tu alternatywą, tylko warstwą obok. Klasyczny analizator pilnuje stylu i podstawowej poprawności przy każdym zapisie pliku, a to narzędzie ocenia stan całości i wyłapuje wzorce architektoniczne.

Kod pisany przez asystentów

Jedno zastosowanie zasługuje na osobne omówienie, bo stało się w ostatnim czasie głównym powodem sięgania po takie narzędzia.

Kod generowany przez asystentów wygląda poprawnie i regularnie zawiera dokładnie te wzorce, które to narzędzie wyłapuje. Efekt uboczny zamiast wyliczenia, właściwości przekazywane przez cztery poziomy, importy zaciągające całą bibliotekę, komponent zostawiony po zmianie kierunku i nieusunięty.

Powód jest zrozumiały. Model generuje kod pasujący do fragmentu, który widzi, bez pełnego obrazu projektu, więc powiela wzorce lokalnie poprawne i globalnie zbędne. Przy dwóch komponentach to niewidoczne, przy dwustu składa się na projekt trudny w utrzymaniu.

Automat sprawdzający ustalony zestaw reguł jest tu skuteczniejszy niż przegląd ludzki, bo takie wzorce są nudne, powtarzalne i łatwe do przeoczenia przy czytaniu dwudziestego pliku tego dnia. Narzędzie znajdzie je wszystkie i za każdym razem tak samo.

Narzędzie da się też podpiąć jako umiejętność dostępna dla asystenta, co zamyka pętlę: asystent pisze kod, uruchamia skan i poprawia to, co sam wprowadził, zanim człowiek w ogóle zobaczy zgłoszenie.

Co zrobić z wynikiem

Raport z listą sześćdziesięciu uwag jest paraliżujący, więc warto mieć plan przejścia od liczby do zmian w kodzie.

Zacznij od podziału na trzy kategorie. Pierwsza to rzeczy do naprawienia teraz: bezpieczeństwo i dostępność, bo obie mają konsekwencje poza kodem. Druga to rzeczy do naprawienia przy okazji, czyli wzorce wydajnościowe i architektoniczne, poprawiane wtedy, gdy i tak dotykasz danego pliku. Trzecia to rzeczy do świadomego pominięcia, bo nie każda reguła pasuje do każdego projektu.

Martwy kod potraktuj osobno, bo to najłatwiejszy zysk w całym raporcie. Usunięcie plików, do których nic nie prowadzi, nie wymaga myślenia o architekturze, nie psuje niczego i od razu zmniejsza to, co trzeba czytać, budować i utrzymywać. Warto natomiast sprawdzić wyniki ręcznie, bo kod ładowany dynamicznie albo używany wyłącznie w konfiguracji bywa oznaczany jako martwy niesłusznie.

Zbędne efekty uboczne zostaw na koniec pierwszego podejścia, mimo że jest ich zwykle najwięcej. Każda taka poprawka wymaga zrozumienia, skąd bierze się wartość i co się dzieje przy zmianie właściwości, więc to jest praca na uwagę, a nie na masowe zamiany.

Zapisz wynik początkowy, zanim cokolwiek zmienisz. Bez punktu odniesienia po dwóch tygodniach nie odróżnisz poprawy od wrażenia poprawy, a to jest jedyna miara mówiąca, czy praca miała sens.

Do takiego pomiaru narzędzie ma dwa wyjścia nadające się do zapisania. Pierwsze zwraca samą liczbę, drugie pełny raport w formacie nadającym się do dalszego przetwarzania.

Code
Bash
npx react-doctor@latest --score >> historia-oceny.txt
npx react-doctor@latest --json --json-out raporty/$(git rev-parse --short HEAD).json

Nazwanie pliku skrótem zmiany daje historię, w której widać nie tylko czy ocena rośnie, ale też przy której zmianie spadła. To jest różnica między wiedzą, że coś się pogorszyło, a wiedzą, co to było.

Granice tego podejścia

Warto powiedzieć wprost, czego takie narzędzie nie zrobi, bo ocena liczbowa kusi, żeby traktować ją jako całą prawdę o projekcie.

Nie oceni architektury. Projekt z czystym podziałem na warstwy i projekt, w którym logika biznesowa siedzi w komponentach, mogą dostać tę samą ocenę, jeśli oba przestrzegają reguł składniowych.

Nie oceni testów. Brak jakiegokolwiek pokrycia testami nie obniża wyniku, choć dla długoterminowego utrzymania projektu znaczy więcej niż większość wyłapanych wzorców.

Nie oceni, czy kod robi to, co powinien. Komponent liczący rabat z błędem w progu przejdzie skan bez uwag, bo z punktu widzenia reguł jest napisany poprawnie.

Nie zastąpi też rozmowy o tym, dokąd projekt zmierza. Ocena osiemdziesiąt pięć w module przeznaczonym do usunięcia za kwartał jest informacją bez żadnej wartości praktycznej, a narzędzie o takich planach nie wie.

Wniosek nie brzmi „nie używaj", tylko określa miejsce. To jest szybki termometr, który mówi, czy coś się pogarsza i gdzie leżą powtarzalne problemy. Diagnoza całości pozostaje pracą ludzi, którzy ten projekt znają.

Typowe błędy

Pierwszy to traktowanie oceny jako procentu jakości kodu. To wskaźnik wyliczany po stronie dostawcy z listy naruszonych reguł, a nie udział poprawnego kodu w całości projektu.

Drugi to ustawienie wysokiej bramki w istniejącym projekcie. Bramka nieosiągalna zostaje wyłączona w ciągu tygodnia i przestaje chronić cokolwiek.

Trzeci to pozostawienie wszystkich reguł mimo świadomej decyzji o niestosowaniu części z nich. Szum obniża wartość pozostałych uwag.

Czwarty to uruchamianie ręczne zamiast wpięcia w proces budowania. Nikt nie pamięta o uruchamianiu narzędzi, więc automat wygrywa z dobrymi chęciami.

Piąty to oczekiwanie oceny sensu rozwiązania. Narzędzie sprawdza ustalone reguły, a pytanie o to, czy rozwiązanie pasuje do architektury systemu, należy do recenzenta znającego projekt.

Szósty to układanie kolejności poprawek według liczby wystąpień. Usługa licząca wynik przypisuje regułom poziomy od P0 do P3 i to jest lepszy porządek niż licznik przy każdej regule.

FAQ

Czy React Doctor używa modelu językowego?

Nie. Sprawdza ustalony zestaw reguł, więc wynik jest powtarzalny i ten sam kod zawsze daje tę samą ocenę. To czyni go odpowiednim na bramkę w procesie budowania, w odróżnieniu od narzędzi opartych o modele językowe, które lepiej sprawdzają się przy przeglądzie zmian.

Skąd bierze się ocena?

Skan idzie lokalnie, ale samą punktację liczy usługa dostawcy, do której trafia oczyszczona lista znalezisk i metadane przebiegu, bez kodu źródłowego. Bez sieci wynik się nie pojawia, a przełącznik --no-score odcina to wysyłanie razem z odsyłaczem do udostępniania i zgłaszaniem awarii.

Czy zastąpi klasyczny analizator kodu?

Nie, to warstwa obok. Klasyczny analizator pilnuje stylu i podstawowej poprawności przy każdym zapisie pliku. To narzędzie ocenia stan całego projektu i wyłapuje wzorce charakterystyczne dla Reacta, których zwykły zestaw reguł nie obejmuje.

Czy działa z Next.js i innymi frameworkami?

Tak, wykrywa użyty framework sam i dobiera do niego reguły. Obsługiwane są między innymi projekty na Next.js, narzędziach budujących nowej generacji oraz aplikacje mobilne w Reakcie.

Po co uruchamiać to przy kodzie pisanym z pomocą asystenta?

Bo asystent widzi fragment, a nie całość projektu, więc powiela wzorce lokalnie poprawne i globalnie zbędne: efekty zamiast wyliczeń, przekazywanie właściwości przez wiele poziomów, kod pozostawiony po zmianie kierunku. Automat znajduje je za każdym razem tak samo, a człowiek czytający dwudziesty plik tego dnia niekoniecznie.

Dokumentacja stoi na stronie projektu, a pakiet znajdziesz w rejestrze npm.