ESLint vs Prettier: Różnice i Jak je Połączyć

Zapisujesz plik, Prettier go formatuje, a ESLint natychmiast zgłasza błąd w linii, którą Prettier właśnie dotknął. Oba narzędzia są skonfigurowane, oba działają — i zamiast pomagać, walczą ze sobą. Te dwa narzędzia robią różne rzeczy. Problem w tym, że oba mają zdanie na temat jednej sprawy: jak kod ma wyglądać na ekranie. Co ESLint faktycznie sprawdza ESLint rozkłada kod na abstrakcyjne drzewo składniowe i uruchamia reguły na jego strukturze. Największa wartość pochodzi z reguł, które wyłapują realne bugi: zmienną, która nigdy nie została zdefiniowana, nieosiągalny return po innym return, nieużywany import, który został po refaktoryzacji, zduplikowany klucz w obiekcie, który bez ostrzeżenia nadpisuje pierwszy. To kontrole semantyczne — ESLint czyta, co kod robi. ...

1 listopada 2026 · 6 min · 1075 słów · SpaghettiCoder

React useEffect Wyjaśniony: Zależności i Cleanup

Komponent czatu łączy się ponownie przez WebSocket za każdym razem, gdy wpisujesz literę w polu wyszukiwania, które nie ma nic wspólnego z czatem. Inny komponent renderuje się w kółko, aż karta się zawiesza. Trzeci wywołuje swój useEffect dwa razy przy montowaniu, ale tylko w trybie deweloperskim. Żaden z tych przypadków nie jest błędem Reacta. Dwa pierwsze to tablica zależności robiąca dokładnie to, co jej kazano, a trzeci to Strict Mode sprawdzający, czy twój efekt umie się po sobie posprzątać. ...

29 października 2026 · 7 min · 1430 słów · SpaghettiCoder

Wyrażenia Regularne Wyjaśnione: Jak Naprawdę Działa Regex

<.+> dla <b>bold</b> and <i>italic</i> nie znajduje <b>. Znajduje cały ciąg, od pierwszego < do samego ostatniego >. Nic nie jest zepsute. To właśnie ma robić zachłanny (greedy) kwantyfikator, i to jest też najczęstszy błąd typu “regex matchuje zbyt dużo”. Gdy już wiesz, co silnik robi podczas czytania wzorca, ten błąd i większość jego krewnych przestają być zagadką. Jak silnik regex czyta twój wzorzec Silnik regex nie porównuje wzorca z ciągiem tak, jak porównuje się dwa ciągi pod kątem równości. Silniki, które używasz codziennie (re w Pythonie, RegExp w JavaScript, PCRE, .NET, Java) są regex-directed: przechodzą przez wzorzec od lewej do prawej, token po tokenie, i dla każdego tokenu próbują skonsumować znaki z ciągu w aktualnej pozycji. Gdy token się dopasuje, silnik przesuwa wskaźnik wzorca i wskaźnik ciągu. Gdy token zawodzi, silnik robi backtracking: wraca do ostatniego miejsca, w którym miał wybór, na przykład kwantyfikator, który mógł dopasować mniej znaków, albo gałąź alternatywy, której jeszcze nie spróbował, i wybiera drugą opcję. ...

28 października 2026 · 7 min · 1393 słów · SpaghettiCoder

Generics w TypeScript Wyjaśnione z Przykładami

Czemu any odbiera przekazany typ? Otypuj parametr jako any i TypeScript przestaje sprawdzać wszystko, co wychodzi z funkcji: 1 2 3 4 5 6 function firstElement(arr: any[]): any { return arr[0]; } const n = firstElement([1, 2, 3]); n.toUpperCase(); // kompiluje się, wywala w czasie działania Ty wiesz, że przekazałeś tablicę liczb. Kompilator nie wie, bo any mówi mu, żeby przestał patrzeć. n wraca jako any, więc wywołanie metody string na liczbie kompiluje się bez problemu i wyrzuca TypeError: n.toUpperCase is not a function przy uruchomieniu. ...

27 października 2026 · 7 min · 1382 słów · SpaghettiCoder

Intersection Observer: Lazy Loading i Infinite Scroll

Listener scroll na window może odpalać się setki razy podczas jednego przesunięcia ekranu. Jeśli przy każdym takim evencie wywołujesz getBoundingClientRect() na każdej karcie w feedzie, pięćdziesiąt obrazów wystarczy, żeby strona zaczęła się zacinać. Intersection Observer API zdejmuje to sprawdzenie ze ścieżki scrolla: rejestrujesz, jakie elementy obserwować, a przeglądarka informuje cię, gdy ich widoczność naprawdę się zmienia. Jak działa IntersectionObserver Observer obserwuje jeden lub więcej elementów target względem root (domyślnie viewport) i wywołuje callback, gdy target przekroczy próg widoczności. ...

21 października 2026 · 5 min · 958 słów · SpaghettiCoder

Closure w JavaScript Wyjaśnione z Przykładami

Co to jest closure w JavaScript? 1 2 3 4 5 6 7 8 9 10 11 12 function makeCounter() { let count = 0; return function () { count += 1; return count; }; } const counter = makeCounter(); console.log(counter()); // 1 console.log(counter()); // 2 console.log(counter()); // 3 makeCounter działa raz, zwraca funkcję i na tym koniec: jej stack frame już nie istnieje. Mimo to każde wywołanie counter() wciąż odczytuje i aktualizuje count — zmienną zadeklarowaną wewnątrz funkcji, która już się zakończyła. count nie wraca do 0 i nie jest kopiowana. To wciąż ta sama zmienna, żywa, trzy wywołania później. ...

19 października 2026 · 6 min · 1222 słów · SpaghettiCoder

npm vs Yarn vs pnpm: Którego Menedżera Pakietów Używać

Odpal npm install w projekcie, a potem pnpm install na tym samym package.json – dostajesz dwa różne drzewa node_modules i dwa różne lockfile’y. Dodaj kolegę, który sięga po Yarn, i w historii repozytorium lądują trzy lockfile’y, każdy opisujący nieco inne drzewo zależności. Wszystkie trzy czytają ten sam package.json i pobierają z tego samego rejestru npm. Nie zgadzają się co do tego, co zapisać na dysku. Jak npm, Yarn i pnpm układają node_modules Struktura npm jest płaska. Każdy pakiet, którego potrzebują twoje zależności, niezależnie od tego, jak głęboko w drzewie, trafia do głównego node_modules, jeśli nie ma konfliktu wersji. To domyślne zachowanie od npm 3. Efekt uboczny: twój kod może zrobić require() albo import pakietu, którego nigdy nie wpisałeś do package.json, o ile cokolwiek innego w drzewie od niego zależy. Działa to, dopóki ten inny pakiet nie usunie tej zależności w minor release – wtedy twój build się psuje, mimo że w twoim kodzie nic się nie zmieniło. To jest phantom dependency, a struktura npm nic z tym nie robi. ...

17 października 2026 · 7 min · 1304 słów · SpaghettiCoder

Obsługa Błędów Fetch API w JavaScript

Owiń wywołanie fetch() w try/catch, trafiasz na endpoint, który odpowiada 404, a blok catch nigdy się nie uruchamia. Promise się rozwiązuje. res.json() parsuje to, co serwer odesłał, często payload błędu w stylu {"error": "user not found"}, a reszta funkcji traktuje to jak żądany rekord. Żadnego wyjątku, żadnego ostrzeżenia w konsoli. Złe dane płyną dalej, aż coś inne się na nich wywala. 1 2 3 4 5 6 7 8 9 async function getUser(id) { try { const res = await fetch(`/api/users/${id}`); const user = await res.json(); return user; // przy 404 to jest { error: "user not found" } } catch (err) { console.error('Failed to load user:', err); } } Ten catch odpala się tylko dla żądania, które nigdy się nie kończy. Wszystko inne wymaga sprawdzenia, które musisz napisać samodzielnie. ...

14 października 2026 · 7 min · 1330 słów · SpaghettiCoder

Debounce vs Throttle w JavaScript: Kiedy Używać Którego

Pole wyszukiwania, które wysyła zapytanie przy każdym naciśnięciu klawisza, wysyła pięć zapytań dla “redis”, a cztery z nich są już nieaktualne, zanim wróci odpowiedź. Handler scroll, który przelicza layout, odpala się setki razy na sekundę i powoduje szarpanie strony. W obu przypadkach ten sam problem: zdarzenie DOM odpala się dużo częściej, niż handler musi się wykonać. Debounce i throttle rozwiązują to na dwa różne sposoby. Co robi debounce, a co robi throttle Debounce czeka, aż zdarzenie przestanie się odpalać na ustalony czas, i wtedy wykonuje się raz. Każde nowe wywołanie resetuje zegar. Jeśli zdarzenie nigdy się nie zatrzymuje, funkcja nigdy się nie wykonuje. Pole wyszukiwania to typowy przypadek: czekaj, aż użytkownik zrobi przerwę w pisaniu, a potem wyślij zapytanie z tym, co wpisał na końcu. ...

8 października 2026 · 7 min · 1292 słów · SpaghettiCoder

LocalStorage vs SessionStorage vs Cookies: co wybrać

Endpoint logowania odsyła JWT, a Ty masz trzy miejsca, w których możesz go trzymać: cookie, localStorage albo sessionStorage. Wybierzesz źle i albo błąd XSS wyniesie token na zewnątrz, albo token nigdy nie dotrze do Twojego API. Wszystkie trzy mechanizmy przechowują stringi w przeglądarce. Różnią się tym, kto może je odczytać, jak długo żyją i czy serwer w ogóle je widzi. Czym różnią się localStorage, sessionStorage i cookies localStorage i sessionStorage to ten sam interfejs, Storage: setItem, getItem, removeItem, clear, klucze i wartości w postaci stringów. Różnica leży w czasie życia. localStorage przetrwa zamknięcie przeglądarki i restart komputera, i zostaje tam, dopóki coś go nie wyczyści. Safari jest wyjątkiem: z włączonym tracking prevention usuwa dane zapisane przez skrypt dla strony, z którą użytkownik nie miał kontaktu od siedmiu dni. sessionStorage należy do jednej karty i umiera, gdy ta karta się zamyka. Wpisz ten sam adres w drugiej karcie i dostaniesz nowy, pusty sessionStorage — tylko opcja “Duplikuj kartę” kopiuje go dalej. ...

5 października 2026 · 7 min · 1358 słów · SpaghettiCoder