Budowanie prostego narzędzia do lintowania
Twórz niestandardowe narzędzie diagnostyczne za pomocą API kompilatora.
Budowanie prostego narzędzia do lintowania to bezpłatna lekcja TypeScript Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej TypeScript Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs TypeScript Academy zawiera 4 lekcji w sumie.
Czym jest narzędzie lintujące
Narzędzie lintujące analizuje kod źródłowy, aby zgłaszać problemy ze stylem lub poprawnością. Użycie API kompilatora TypeScriptu pozwala tworzyć reguły uwzględniające typy, których same wtyczki ESLint nie potrafią zapewnić.
// Goal: warn when console.log is called in TypeScript filesKonfiguracja projektu
Utwórz skrypt Node.js, który wczytuje program TypeScriptu, przechodzi po AST i zgłasza diagnostykę.
import ts from "typescript";
import path from "path";
const files = ["src/index.ts"];
const program = ts.createProgram(files, { strict: true });Definiowanie reguły
Reguła to funkcja, która otrzymuje węzeł AST i zwraca opcjonalny komunikat diagnostyczny, jeśli reguła została naruszona.
type Diagnostic = { file: string; line: number; message: string };
function noConsoleLog(node: ts.Node, sf: ts.SourceFile): Diagnostic | null {
if (!ts.isCallExpression(node)) return null;
const expr = node.expression.getText(sf);
if (expr !== "console.log") return null;
const { line } = sf.getLineAndCharacterOfPosition(node.pos);
return { file: sf.fileName, line: line + 1, message: "No console.log allowed" };
}Przechodzenie po AST
Napisz rekurencyjną funkcję przechodzącą po drzewie, która stosuje wszystkie reguły do każdego węzła w każdym pliku źródłowym.
function walk(
node: ts.Node,
sf: ts.SourceFile,
rules: ((n: ts.Node, sf: ts.SourceFile) => Diagnostic | null)[]
): Diagnostic[] {
const diags: Diagnostic[] = [];
for (const rule of rules) {
const d = rule(node, sf);
if (d) diags.push(d);
}
ts.forEachChild(node, child => diags.push(...walk(child, sf, rules)));
return diags;
}Uruchamianie lintera
Przejdź po wszystkich plikach źródłowych, zastosuj reguły i wypisz diagnostykę.
const rules = [noConsoleLog];
const allDiagnostics: Diagnostic[] = [];
for (const sf of program.getSourceFiles()) {
if (!sf.isDeclarationFile) {
allDiagnostics.push(...walk(sf, sf, rules));
}
}
allDiagnostics.forEach(d =>
console.log(`${d.file}:${d.line} — ${d.message}`)
);Dodawanie reguły uwzględniającej typy
Użyj sprawdzarki typów do tworzenia reguł zależnych od typu TypeScriptu danego wyrażenia.
const checker = program.getTypeChecker();
function noAnyReturn(node: ts.Node, sf: ts.SourceFile): Diagnostic | null {
if (!ts.isFunctionDeclaration(node)) return null;
const sig = checker.getSignatureFromDeclaration(node);
if (!sig) return null;
const ret = checker.getReturnTypeOfSignature(sig);
if (ret.flags & ts.TypeFlags.Any) {
const { line } = sf.getLineAndCharacterOfPosition(node.pos);
return { file: sf.fileName, line: line + 1, message: "Function returns any" };
}
return null;
}Kod wyjścia dla CI
Zwracaj niezerowy kod wyjścia po znalezieniu diagnostyki, aby potoki CI mogły przerwać budowanie.
if (allDiagnostics.length > 0) {
console.error(`${allDiagnostics.length} lint error(s)`);
process.exit(1);
}
process.exit(0);Reguła: brak nieużywanych zmiennych
API kompilatora udostępnia diagnostykę dotyczącą nieużywanych zmiennych za pośrednictwem ts.getPreEmitDiagnostics, uzupełniając niestandardowe reguły o wbudowane sprawdzanie.
const preEmit = ts.getPreEmitDiagnostics(program);
preEmit.forEach(d => {
const msg = ts.flattenDiagnosticMessageText(d.messageText, "
");
console.log(msg);
});Reguła: wymagaj typów zwracanych
Reguła ostrzegająca, gdy funkcjom brakuje jawnych adnotacji typu zwracanego, pomaga egzekwować dbałość o dokumentację.
function requireReturnType(node: ts.Node, sf: ts.SourceFile): Diagnostic | null {
if (!ts.isFunctionDeclaration(node)) return null;
if (!node.type) {
const { line } = sf.getLineAndCharacterOfPosition(node.pos);
return { file: sf.fileName, line: line + 1, message: "Missing return type" };
}
return null;
}Porównanie z ESLint
Niestandardowy linter uzupełnia ESLint. Używaj ESLint do reguł dotyczących stylu, a narzędzia opartego na API kompilatora TypeScriptu do reguł uwzględniających typy, których ESLint nie potrafi wyrazić.
// ESLint: stylistic and common pattern rules
// Compiler API linter: deep type reasoning, custom constraintsPodsumowanie: budowanie lintera
Linter oparty na API kompilatora TypeScriptu tworzy program, przechodzi po AST za pomocą reguł, opcjonalnie odpyta sprawdzarkę typów i zwraca niezerowy kod wyjścia w przypadku błędów. Takie podejście umożliwia tworzenie reguł lintowania naprawdę uwzględniających typy.
Szybkie sprawdzenie
Co daje linterowi opartemu na API kompilatora przewagę nad ESLint?
Czego się Państwo nauczyli
Zbudowali Państwo prosty linter TypeScriptu za pomocą API kompilatora: wczytali program, przeszli po AST, zastosowali reguły (opcjonalnie uwzględniające typy) i zgłosili diagnostykę. To podstawa niestandardowej analizy statycznej w każdym projekcie TypeScriptu.
Często zadawane pytania
Czy lekcja „Budowanie prostego narzędzia do lintowania” jest bezpłatna?
Tak — pełny tekst „Budowanie prostego narzędzia do lintowania” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu TypeScript Academy, przejdź na CoddyKit PRO. Kurs TypeScript Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Budowanie prostego narzędzia do lintowania”?
Twórz niestandardowe narzędzie diagnostyczne za pomocą API kompilatora. Ćwiczysz TypeScript Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć TypeScript Academy?
Nie wymagamy żadnego doświadczenia. TypeScript Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.
Ile czasu zajmuje lekcja „Budowanie prostego narzędzia do lintowania”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji TypeScript Academy?
Tak. Każda lekcja TypeScript Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Tworzenie programu TypeScript za pomocą API
- Przechodzenie po AST za pomocą odwiedzających
- Niestandardowe transformatory i generowanie kodu
- Budowanie prostego narzędzia do lintowania