Krótki Opis:
Dowiedz się, jak zintegrować ESLint z projektem Angular, aby wcześnie wychwytywać błędy, egzekwować spójne standardy kodowania i poprawić współpracę w zespole. Niezależnie od tego, czy tworzysz małą aplikację, czy skalujesz system korporacyjny, ESLint to pierwsza linia obrony dla czystego i łatwego w utrzymaniu kodu.
Krótkie Podsumowanie:
W tym artykule przechodzimy przez proces dodawania ESLint do projektu Angular. ESLint to narzędzie do statycznej analizy kodu, które pomaga znaleźć problematyczne wzorce i egzekwować najlepsze praktyki.
Dowiesz się, jak:
- Zainstalować ESLint jako zależność deweloperską
- Nowsze wersje Angulara (v13+) często zawierają ESLint domyślnie, gdy tworzysz nowy projekt za pomocą ng new.
- Dodać skrypty lintowania do pliku package.json
- Dostosować reguły
- Uruchomić ESLint na bazie kodu za pomocą CLI
Na koniec będziesz mieć projekt, który nie tylko działa, ale również jest chroniony przez spójny zestaw standardów kodowania.
Wprowadzenie:
Bezproblemowa integracja ESLint z projektem Angular: Przewodnik krok po kroku
W dynamicznie zmieniającym się świecie tworzenia aplikacji webowych, utrzymanie czystego, spójnego i wolnego od błędów kodu jest kluczowe. Dla programistów Angular oznacza to zmianę narzędzi. Wraz z wycofaniem TSLint w Angularze od wersji 13, ESLint stał się nowym standardem lintowania kodu TypeScript.
Ten przewodnik przeprowadzi Cię przez proces dodawania i konfigurowania ESLint w aplikacji Angular. Omówimy niezbędne polecenia, szczegółowo wyjaśnimy wygenerowany plik konfiguracyjny i pokażemy, jak automatycznie naprawiać problemy wykryte przez linter.
Zanim przejdziemy do konfiguracji, poznajmy kluczowe korzyści z używania ESLint w każdym nowoczesnym projekcie JavaScript lub TypeScript — zwłaszcza w dużych lub zespołowych bazach kodu, takich jak Angular czy monorepo Nx.
Oto najważniejsze korzyści:
- Wczesne wykrywanie błędów
ESLint wykrywa takie problemy jak:
- Niezadeklarowane zmienne
- Nieużywane importy
- Nieprawidłowe typy (przez @typescript-eslint)
- Niewłaściwe użycie async/await lub Promise
Poprawianie błędów przed wykonaniem kodu = bezpieczniejszy kod + szybsze debugowanie
- Spójny styl kodu
ESLint automatycznie egzekwuje konwencje kodowania:
- camelCase vs snake_case
- Spójne wcięcia i odstępy
- Styl cudzysłowów (’ vs „)
- Funkcje strzałkowe vs deklaracje funkcji
Połącz z Prettierem dla automatycznego formatowania!
- Lepsza współpraca w zespole
- Kod jest bardziej czytelny i przewidywalny
- Mniej subiektywnych sporów podczas code review
- Wspólne reguły dla wszystkich członków zespołu
„Linter nie pozwolił” lepsze niż kłótnie w komentarzach do PR-ów
- Wyższa jakość i łatwość utrzymania kodu
Reguły lintowania wspierają:
- Mniejsze funkcje i komponenty
- Właściwe obsługiwanie błędów
- Jawne typy zwracane (przez @typescript-eslint)
- Unikanie antywzorców jak any, zagnieżdżone callbacki czy silnie sprzężone moduły
Czysty kod = łatwiejsze testowanie, refaktoryzacja i skalowanie
- Informacje zwrotne w czasie rzeczywistym w edytorze
ESLint integruje się z VS Code, WebStorm i innymi
- Pokazuje błędy już podczas pisania (czerwone zygzaki)
- Pomaga młodszym programistom uczyć się dobrych praktyk
- Ostrzeżenia lintujące są jak sygnalizacja świetlna dla Twojego kodu
- Egzekwowanie reguł architektury (np. w monorepo Nx)
W Nx lub dużych aplikacjach Angular ESLint może wymuszać:
- Granice modułów (@nrwl/nx/enforce-module-boundaries)
- Poprawne ścieżki importów
- Warstwowanie zgodne z domeną
Zapobiega powstawaniu „spaghetti architecture” w monorepo
- Unikanie problemów z bezpieczeństwem i wydajnością
Niektóre wtyczki (np. eslint-plugin-security) wykrywają:
- Użycie eval()
- Niebezpieczne wzorce regex
- Globalne zmienne wyciekające do środowiska
Lintowanie uzupełnia bezpieczne praktyki programistyczne
- Automatyzacja i integracja z CI/CD
- ESLint świetnie działa w pipeline’ach CI/CD
- Blokuje PR-y, które nie spełniają reguł lintowania
- Automatyczna naprawa błędów przez eslint –fix
Uwaga: Od wersji ESLint 9.0.0 domyślnym plikiem konfiguracyjnym jest teraz eslint.config.js.
Jeśli używasz pliku .eslintrc.*, postępuj zgodnie z przewodnikiem migracyjnym, aby zaktualizować swój plik konfiguracyjny do nowego formatu:
https://eslint.org/docs/latest/use/configure/migration-guide
Egzekwuj jakość przed scaleniem, a nie po.
Dodawanie ESLint do Twojego projektu Angular
Rozpoczęcie pracy jest proste dzięki Angular CLI i schematom @angular-eslint. Aby dodać ESLint do swojego projektu, uruchom w terminalu następujące polecenie:
ng add @angular-eslint/schematics
To polecenie zainstaluje najnowszą wersję @angular-eslint i jej zależności.
Migracja z TSLint (narzędzie przestarzałe)
W większości przypadków ta automatyczna migracja działa bezproblemowo. Jednak jeśli napotkasz jakiekolwiek problemy lub chcesz przeprowadzić konwersję ręcznie dla konkretnego projektu w swoim workspace, możesz użyć poniższego polecenia.
Działa ono w starszych wersjach Angulara – do wersji 13. Nazwę swojego projektu znajdziesz w pliku angular.json.
# Deprecated: For older Angular versions (<=13) only
ng g @angular-eslint/schematics:convert-tslint-to-eslint project-name
To polecenie nie działa w nowych wersjach (13+); zostało oznaczone jako przestarzałe dla nowszych wersji.
Migracja z TSLint
Pomiń ten krok, jeśli już używasz ESLint.
Jeśli nadal korzystasz z TSLint, oto ręczny sposób na usunięcie tej zależności.
Jeśli używasz nowoczesnej wersji Angulara i chcesz ręcznie usunąć TSLint po dodaniu ESLint, możesz wykonać następujące kroki:
npx ng add @angular-eslint/schematics
npm uninstall tslint codelyzer
rm tslint.json
ZDJĘCIE!
Inteligentnie używa tslint-to-eslint-config, aby automatycznie zmigrować Twoją istniejącą konfigurację TSLint (tslint.json) do nowego formatu ESLint, tworząc plik .eslintrc.json w katalogu głównym Twojego workspace.
Zaktualizuj cel lintowania w pliku angular.json
Po konwersji upewnij się, że Twój plik angular.json używa ESLint:
Wtyczki ESLint dla projektów Angular
Pakiety @angular-eslint/*:
Wtyczka | Co robi |
@angular-eslint/eslint-plugin | Reguły lintowania specyficzne dla Angulara w plikach .ts |
@angular-eslint/template-parser | Parser umożliwiający ESLint zrozumienie składni szablonów HTML Angulara |
@angular-eslint/eslint-plugin-template | Reguły lintowania dla szablonów Angulara (.html i szablony inline) |
@typescript-eslint/* | Reguły lintowania dla TypeScript (np. no-unused-vars, sprawdzanie typów) |
Uwaga:
Używając @angular-eslint/eslint-plugin-template, konieczne jest zainstalowanie również @angular-eslint/template-parser.
Oba pełnią różne, ale ściśle powiązane funkcje.
Pomyśl o tym jak o tłumaczu i korektorze gramatycznym dla konkretnego dialektu:
- @angular-eslint/template-parser → Tłumacz
- @angular-eslint/eslint-plugin-template → Korektor gramatyczny
Inne wtyczki/pakiety:
- eslint-plugin-import
- eslint-config-prettier
- eslint-plugin-prettier → potrzebny, gdy konfigurujesz Prettier razem z ESLint
Jeśli używasz Prettiera, musisz również utworzyć plik .prettierrc w swoim projekcie. Przykład:
{
"singleQuote": true,
"semi": false,
"printWidth": 100
}
Gdy konfiguracja ESLinta będzie zakończona, polecenie ng lint, które wcześniej mogło nie być skonfigurowane, zostanie teraz powiązane z ESLint i będzie zgłaszać ostrzeżenia lub błędy zgodnie z nowo ustawionymi regułami.
Lintowanie musi być również skonfigurowane w pliku angular.json.
Wszystkie te wtyczki powinny być zainstalowane jako zależności developerskie:
npm install --save-dev packagename
Podczas konfigurowania tych wtyczek należy również dodać odpowiednie reguły.
Poniżej przykład pliku eslint.json, który można rozbudować o dodatkowe reguły według potrzeb.
ZDJĘCIE!
Zrozumienie konfiguracji .eslintrc.json
Serce Twojej nowej konfiguracji lintowania to plik .eslintrc.json. Rozbijmy jego strukturę, aby zrozumieć, jak zarządza jakością Twojego kodu.
{
"root": true,
"ignorePatterns": [
"projects/**/*",
"dist"
],
"overrides": [
{
"files": [
"*.ts"
],
"parserOptions": {
"project": [
"tsconfig.json",
"e2e/tsconfig.json"
],
"createDefaultProgram": true
},
"extends": [
"plugin:@angular-eslint/recommended",
"plugin:@angular-eslint/template/process-inline-templates",
"plugin:import/recommended",
"plugin:import/typescript",
"plugin:prettier/recommended",
"eslint-config-prettier"
],
"rules": {
"@angular-eslint/component-selector": [
"error",
{
"prefix": "app",
"style": "kebab-case",
"type": "element"
}
],
"@angular-eslint/directive-selector": [
"error",
{
"prefix": "app",
"style": "camelCase",
"type": "attribute"
}
]
}
},
{
"files": [
"*.html"
],
"extends": [
"plugin:@angular-eslint/template/recommended"
],
"rules": {}
}
]
}
Omówienie konfiguracji:
- „root”: true
Oznacza, że jest to główny plik konfiguracyjny ESLint w Twoim projekcie. ESLint przestanie szukać innych plików konfiguracyjnych w katalogach nadrzędnych. - „ignorePatterns”: […]
Tablica określająca pliki i foldery, które ESLint powinien ignorować podczas lintowania. W tej konfiguracji ignorowane są wszystkie pliki w folderach projects i dist.
Oznacza to, że lint pominie Twoje biblioteki znajdujące się w folderze projects/.
Inny przykład: jeśli chcesz zignorować wszystko w katalogu projects/ z wyjątkiem biblioteki o nazwie my-ui-kit, zmodyfikuj ignorePatterns w następujący sposób:
// .eslintrc.json
"ignorePatterns": [
"projects/**/*", // First, ignore everything inside the projects directory
"!projects/my-ui-kit", // Then, create an exception to re-include this specific library
"dist/"
]
Użyj .eslintignore, jeśli uruchamiasz ESLint ręcznie.
Utwórz plik .eslintignore w katalogu głównym projektu z zawartością:
!src/app/**
To ignoruje wszystko oprócz katalogu src/app.
Używaj tego tylko wtedy, gdy uruchamiasz ESLint ręcznie, a nie za pomocą ng lint.
- „overrides”: […]: ta funkcjonalność pozwala na zdefiniowanie specyficznych konfiguracji dla różnych typów plików.
- Pliki TypeScript (*.ts):
- „parserOptions”: konfiguruje, w jaki sposób ESLint powinien analizować kod TypeScript.
- „project”: wskazuje na pliki tsconfig.json, co umożliwia stosowanie reguł opartych na typach.
- „createDefaultProgram”: mechanizm zapasowy, który pozwala ESLint analizować pliki, które nie są jawnie uwzględnione w tsconfig.json podanym w tablicy project.
- „parserOptions”: konfiguruje, w jaki sposób ESLint powinien analizować kod TypeScript.
- Pliki TypeScript (*.ts):
Ostrzeżenie dotyczące wydajności:
Chociaż createDefaultProgram: true daje wygodę, zapobiegając błędom typu „plik nie znaleziony w projekcie”, wiąże się to z dużym kosztem wydajnościowym.
Wymusza to na parserze tworzenie nowego, oddzielnego programu TypeScript dla każdego pliku, który nie został odnaleziony, co może dramatycznie spowolnić proces lintowania — zwłaszcza w dużych bazach kodu. Opcja ta jest przeznaczona głównie dla kompatybilności wstecznej i powinna być używana ostrożnie.
Wskazówka: Optymalizacja wydajności lintowania w monorepo.
Dla deweloperów pracujących w monorepo z wieloma bibliotekami (np. w katalogu projects/), sposób konfiguracji parserOptions ma ogromny wpływ na wydajność i dokładność.
Wolniejsze, pojedyncze podejście konfiguracyjne:
Typowa początkowa konfiguracja może wyglądać tak — wskazuje jeden plik tsconfig.json w katalogu głównym:
// .eslintrc.json (in the workspace root)
{
// ...
"overrides": [
{
"files": ["*.ts"],
"parserOptions": {
"project": ["tsconfig.json"], // Points to one central tsconfig
"createDefaultProgram": true // SLOW: Used as a fallback for library files not in the main tsconfig
},
// ...
}
]
}
Ta konfiguracja zmusza ESLint do zbudowania ogromnego programu dla całej aplikacji, a dla każdego pliku biblioteki nieobjętego tym tsconfig używa wolnej opcji zapasowej createDefaultProgram. To nieefektywne i może prowadzić do długiego czasu oczekiwania na wyniki lintowania.
Szybsze, zalecane podejście wielokonfiguracyjne:
Najlepszą praktyką pod względem wydajności i łatwości utrzymania jest przypisanie każdemu projektowi (aplikacji lub bibliotece) własnej konfiguracji ESLint.
Gdy tworzysz nową bibliotekę za pomocą ng generate library my-lib, Angular CLI zazwyczaj tworzy dedykowany plik .eslintrc.json dla tej biblioteki.
Struktura wygląda wtedy tak:
- Główny .eslintrc.json: zawiera globalne reguły i wzorce ignorowania.
- Specyficzny .eslintrc.json dla biblioteki: każda biblioteka ma swój własny plik konfiguracyjny, który wskazuje na dedykowany plik tsconfig.
Przykład: projects/my-data-access/.eslintrc.json
{
"extends": "../../.eslintrc.json", // Inherits from the root config
"ignorePatterns": ["!**/*"], // Ensures all files in this lib are linted
"overrides": [
{
"files": ["*.ts"],
"parserOptions": {
// RECOMMENDED: Point to the library's specific tsconfig
"project": ["projects/my-data-access/tsconfig.lib.json"],
// "createDefaultProgram" is no longer needed here!
},
"rules": {
// You can add rules specific to this library here
}
},
{
"files": ["*.html"],
"parserOptions": {
"project": ["projects/my-data-access/tsconfig.lib.json"]
}
}
]
}
Korzyści z tego podejścia:
- Ogromny wzrost wydajności: Kiedy lintujesz konkretną bibliotekę, ESLint musi utworzyć program TypeScript tylko dla tego małego podzbioru plików, co znacznie przyspiesza cały proces.
- Lepsza dokładność: Reguły oparte na typach są bardziej niezawodne, ponieważ działają w oparciu o precyzyjną konfigurację zdefiniowaną dla danej biblioteki.
- Lepsza skalowalność: Wydajność lintowania pozostaje wysoka, nawet gdy Twoje monorepo rośnie, ponieważ każda część jest lintowana niezależnie.
Poświęcając czas na przygotowanie osobnych, ukierunkowanych plików konfiguracyjnych, zapewniasz sobie szybki i wydajny proces tworzenia – niezależnie od rozmiaru projektu.
- „extends”: Określa bazowe konfiguracje, po których dziedziczy Twoja konfiguracja reguł.
- plugin:@angular-eslint/recommended: Zestaw zalecanych reguł lintowania dla kodu TypeScript w Angularze.
- plugin:@angular-eslint/template/process-inline-templates: Umożliwia ESLint analizowanie i lintowanie osadzonych szablonów HTML w plikach komponentów.
- „rules”: W tym miejscu możesz dostosować lub nadpisać odziedziczone reguły. Na przykład reguły @angular-eslint/component-selector i @angular-eslint/directive-selector wymuszają spójne konwencje nazewnictwa dla komponentów i dyrektyw.
- Pliki HTML (*.html):
- „extends”: Dziedziczy z plugin:@angular-eslint/template/recommended, który zapewnia zestaw reguł dobrych praktyk dla szablonów Angulara.
- „rules”: Pozostawione puste, co oznacza, że nie dodano żadnych dodatkowych reguł poza tymi zalecanymi. Oczywiście możesz tutaj dodać własne reguły.
Przydatne reguły JS/TS do włączenia:
"rules": {
"no-console": "warn",
"prefer-const": "error",
"arrow-body-style": ["error", "as-needed"],
"@typescript-eslint/explicit-function-return-type": "warn"
}
Komendy do uruchamiania ESLint
npx ng lint
Automatyczne naprawianie problemów z lintowaniem
Jedną z największych zalet korzystania z lintera jest możliwość automatycznego naprawiania wielu wykrywanych problemów. Aby to zrobić za pomocą ESLinta, możesz uruchomić następujące polecenie — albo bezpośrednio przez npx, albo aktualizując skrypty w pliku package.json według nowego podejścia:
npx eslint . --fix
{
"lint": "ng lint",
"lint:fix": "ng lint --fix"
}
To polecenie informuje ESLinta, aby przeskanował wszystkie pliki w bieżącym katalogu (.) i automatycznie naprawił (–fix) te reguły, które na to pozwalają. Może to zaoszczędzić ogromną ilość czasu i wysiłku potrzebnego do przestrzegania standardów kodowania. Dobrym nawykiem jest okresowe uruchamianie tego polecenia, aby utrzymać czystość kodu.
Uwaga: Od Angulara w wersji 20 ESLint jest instalowany domyślnie.
Reguły ESLinta dla monorepo Nx
Jeśli używasz Nx, ESLint ma głęboką integrację służącą do egzekwowania ograniczeń na poziomie całego workspace’a.
Dla projektu Nx trzeba skonfigurować lint osobno dla każdej biblioteki.
npm install --save-dev @nrwl/eslint-plugin-nx
Postępując zgodnie z tymi krokami, możesz skutecznie zintegrować ESLinta z projektem Angular, zapewniając wyższy standard jakości kodu i bardziej łatwą w utrzymaniu aplikację w dłuższej perspektywie.
Dzięki za przeczytanie. To był kompleksowy przewodnik po konfiguracji ESLinta dla aplikacji Angular.
W kolejnym wpisie omówię, jak skonfigurować ESLint z Husky.
Miłego kodowania!