Wpis
Skill do commit w Next.js: jak sprawic, zeby kazdy commit odpalal testy i blokowal fuszerke
Praktyczna konfiguracja hookow git, Husky i lint-staged, aby kazdy commit uruchamial lint, format i szybkie testy.
Stefan Tyllo
13 lutego 2026

"Skill do commit" w Next.js: jak sprawic, zeby kazdy commit automatycznie odpalal testy i blokowal fuszerke
W projekcie Next.js najlatwiej wpuscic blad nie przez zly feature, tylko przez drobnostki: niedzialajacy test, literowke w typach, import z nieistniejacej sciezki, albo lint, ktory na CI wybuchnie dopiero po merge. Da sie to uciac jednym, prostym mechanizmem: commit przechodzi tylko wtedy, gdy projekt jest w stanie zielonym.
W tym artykule pokazuje, jak zrobic skill do commit - praktycznie: hooki git + skrypty, ktore przy commicie:
- formatuja i lintuja tylko to, co zmieniles,
- uruchamiaja szybkie testy,
- opcjonalnie robia typecheck albo nawet build,
- a jak cos jest nie tak, commit sie nie wykona.
To dziala lokalnie (na Twoim laptopie) i jest najlepszym uzupelnieniem CI, bo lapie problemy zanim w ogole wyjda z Twojej maszyny.
Jakie bramki jakosci warto miec w Next.js
Zanim cos skonfigurujesz, ustal zestaw kontroli. Dla wiekszosci projektow Next.js sensowny podzial wyglada tak:
Pre-commit (ma byc szybkie)
Uruchamiaj rzeczy, ktore powinny trwac sekundy:
- Prettier (formatowanie) - najlepiej na staged files,
- ESLint (
next lint) - tez na staged files, - unit tests (Jest/Vitest) - najlepiej szybka paczka.
Pre-push (moze trwac dluzej)
Rzeczy ciezsze, ale nadal przed wyslaniem:
- TypeScript typecheck (
tsc --noEmit), - build (
next build) - opcjonalnie, - ewentualnie szybkie E2E (Playwright) tylko dla krytycznych zmian.
CI (prawdziwy sad ostateczny)
Na PR lub merge:
- pelny lint,
- pelny typecheck,
- pelne testy,
- build,
- E2E.
Wazne: jesli wrzucisz next build do pre-commit, zniechecisz ludzi do commitowania. Zrob to swiadomie.
Fundament: skrypty w package.json
Najpierw uporzadkuj scripts. Przyklad (dopasuj do tego, co juz masz):
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"lint:fix": "next lint --fix",
"format": "prettier . --write",
"format:check": "prettier . --check",
"typecheck": "tsc --noEmit",
"test": "vitest",
"test:ci": "vitest run",
"precommit": "lint-staged && npm run test:ci",
"prepush": "npm run typecheck && npm run test:ci && npm run build"
}
}
Dlaczego tak?
- lint-staged zajmuje sie tylko tym, co commitujesz.
- test:ci powinno byc deterministyczne (bez watch mode).
- typecheck i build trzymasz poza pre-commit, bo to sa najczestsze czasozjadacze.
Jesli uzywasz Jest, zamien testy np. na:
"test:ci": "jest --ci"
Narzedzia: Husky + lint-staged
To najpopularniejszy zestaw do git hookow w JS i TS.
1) Instalacja
npm i -D husky lint-staged prettier
ESLint w Next.js zwykle juz masz (Next potrafi go dodac). Jesli nie masz:
npm i -D eslint eslint-config-next
2) Inicjalizacja Husky
npx husky init
To utworzy katalog .husky i podlaczy hook pre-commit.
Konfiguracja lint-staged (czyli dotykaj tylko zmienionych plikow)
Dodaj do package.json:
{
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"*.{json,md,css,scss,yml,yaml}": [
"prettier --write"
]
}
}
Uwaga o next lint:
next lintdziala swietnie na caly projekt, ale w pre-commit szybciej jest odpalaceslintbezposrednio na plikach staged (bo lint-staged podaje liste plikow).- Jesli koniecznie chcesz trzymac sie
next lint, mozesz, ale zwykle jest wolniej i mniej precyzyjnie w kontekscie staged files.
Hook pre-commit: odpal skill przy commicie
W pliku .husky/pre-commit ustaw:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm run precommit
To spowoduje, ze przy git commit:
- przejdzie lint-staged (format + lint na staged),
- przejda testy (np. Vitest lub Jest w trybie CI),
- jesli cokolwiek padnie, commit zostanie zablokowany.
Hook pre-push: ciezsze kontrole przed wysylka
Dodaj hook:
npx husky add .husky/pre-push "npm run prepush"
I sprawdz, ze .husky/pre-push wyglada tak:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm run prepush
To cie chroni przed sytuacja:
- testy przeszly, ale typy nie,
- typy przeszly, ale build wybucha (np. przez SSR-only bug),
- u mnie dziala, a pipeline zaraz padnie.
Jak to dopasowac, zeby nie bolalo (wazne w praktyce)
1) Rozdziel testy na szybkie i pelne
Jesli masz duzo testow, zrob dwa targety:
- test:ci - szybkie unit testy,
- test:full - pelen zestaw, ewentualnie integracyjne.
I odpalaj test:ci w pre-commit, a test:full w CI.
2) Typecheck: kiedy w pre-commit, kiedy nie?
- Maly projekt: typecheck w pre-commit jest ok.
- Duzy monorepo: typecheck raczej w pre-push lub CI.
3) Next build w pre-push - rozsadny kompromis
next build potrafi zlapac bledy, ktorych testy nie dotkna (np. SSR/Edge, importy, dynamiczne segmenty, bledy w getServerSideProps itp.).
Jesli build jest szybki, warto.
Bonus: commit skill jako jedno polecenie (opcjonalnie)
Niektorzy lubia dodatkowy workflow: zamiast git commit -m, robia jedno polecenie, ktore:
- odpala checks,
- jesli zielono, robi commit.
Mozesz dodac np. skrypt:
"scripts": {
"commit:smart": "npm run precommit && git commit"
}
Uzycie:
git add .
npm run commit:smart
To nie zastapuje hookow (hooki sa lepsze, bo dzialaja zawsze), ale bywa wygodne.
Debugowanie: czemu commit mi sie blokuje?
Najczestsze powody:
- ESLint zwraca exit code != 0 (nawet jesli cos tylko ostrzega, zalezy od konfiguracji),
- Prettier zmienil plik, ale cos jeszcze failuje,
- testy maja flaki (niedeterministyczne),
- hooki nie odpalaja sie (np. repo bez Husky install, albo ktos ma wylaczone hooki).
Szybki test:
npm run precommit
npm run prepush
Jesli to dziala recznie, a hook nie, problem jest w Husky, uprawnieniach, albo shellu.
I na koniec: nie ufaj tylko lokalnym hookom (CI nadal jest obowiazkowe)
Hooki swietnie lapia bledy wczesnie, ale CI to jedyne miejsce, gdzie:
- srodowisko jest spojne,
- kazdy PR przechodzi ten sam gate,
- mozesz odpalac E2E i build bez kompromisow.
Najlepszy uklad to:
- pre-commit: szybko i bezbolesnie,
- pre-push: pewnosc przed wysylka,
- CI: pelna egzekucja jakosci.
Komentarze
0