Kurs JavaScript i TypeScript · Moduł 6: Podstawy TypeScript
Konfiguracja środowiska (tsconfig.json)
W tej lekcji9
Wprowadzenie: Mapa Parku Jurajskiego
W poprzedniej lekcji poznaliśmy TypeScript jako zaawansowany system bezpieczeństwa dla naszego Parku Jurajskiego. Teraz nadszedł czas, aby zrozumieć, jak skonfigurować ten system - to tak, jakbyśmy projektowali mapę parku, określali strefy bezpieczeństwa i ustawiali poziomy dostępu.
W świecie TypeScript, tę konfigurację zapewnia plik tsconfig.json. To właśnie on określa, jak działa kompilator TypeScript, jakie opcje są włączone, jak rygorystyczne są reguły typowania i wiele innych aspektów.
Dr. Henry Wu, główny genetyk parku, lubi mówić: "Kontrola to iluzja". Ale w przypadku TypeScript, odpowiednia konfiguracja daje nam rzeczywistą kontrolę nad naszym kodem.
Tworzenie pliku tsconfig.json
Zacznijmy od utworzenia podstawowego pliku konfiguracyjnego dla naszego systemu zarządzania Parkiem Jurajskim:
1# Jeśli masz zainstalowany TypeScript globalnie, możesz użyć:
2tsc --init
3
4# Lub za pomocą npx:
5npx tsc --initTa komenda wygeneruje podstawowy plik tsconfig.json z najważniejszymi opcjami (większość z nich będzie zakomentowana). Dla naszego parku dinozaurów, możemy utworzyć niestandardową konfigurację:
1{
2 "compilerOptions": {
3 "target": "es2016",
4 "module": "commonjs",
5 "outDir": "./dist",
6 "rootDir": "./src",
7 "strict": true,
8 "esModuleInterop": true,
9 "skipLibCheck": true,
10 "forceConsistentCasingInFileNames": true
11 },
12 "include": ["src/**/*"],
13 "exclude": ["node_modules", "**/*.spec.ts"]
14}To tak, jakby Dr. Hammond przygotował wytyczne dotyczące funkcjonowania poszczególnych stref w parku.
Najważniejsze opcje konfiguracyjne
Podstawowa struktura projektu
Podobnie jak w parku potrzebujemy określić strefy dla różnych gatunków dinozaurów, w projekcie TypeScript musimy zdefiniować, gdzie znajdują się pliki źródłowe i gdzie będą generowane pliki wynikowe:
1{
2 "compilerOptions": {
3 "outDir": "./dist", // Katalog wynikowy, gdzie będą generowane pliki .js
4 "rootDir": "./src", // Katalog źródłowy, gdzie znajdują się pliki .ts
5 "baseUrl": ".", // Bazowy URL dla ścieżek względnych
6 "paths": { // Aliasy dla ścieżek importów
7 "@models/*": ["src/models/*"],
8 "@utils/*": ["src/utils/*"],
9 "@config/*": ["src/config/*"]
10 }
11 }
12}To tak, jakbyśmy mieli mapę parku z oznaczeniami:
- "src" to nasza główna baza operacyjna
- "dist" to obszar dostępny dla zwiedzających
- Mamy też skróty do ważnych miejsc w parku (laboratorium, centrum kontroli itp.)
Wersja ECMAScript
Podobnie jak park musi być kompatybilny z różnymi gatunkami dinozaurów, nasz kod TypeScript musi być kompatybilny z różnymi środowiskami JavaScript:
1{
2 "compilerOptions": {
3 "target": "es2016", // Do jakiej wersji JS kompilować
4 "module": "commonjs", // System modułów (commonjs, ES modules, etc.)
5 "lib": ["dom", "es2016", "dom.iterable", "scripthost"] // Biblioteki definicji
6 }
7}W naszym parku:
- "target" to jak określenie, z którymi gatunkami dinosaurów jesteśmy w stanie pracować
- "module" to jak system transportu w parku (jeepy, monorail itp.)
- "lib" to jak określenie, jakie narzędzia i sprzęt mamy do dyspozycji
Poziom restrykcyjności
W zależności od gatunków dinozaurów w parku, potrzebujemy różnych poziomów zabezpieczeń. Podobnie w TypeScript, możemy regulować poziom rygorystyczności sprawdzania typów:
1{
2 "compilerOptions": {
3 "strict": true, // Włącza wszystkie poniższe opcje rygorystyczne
4 "noImplicitAny": true, // Wymusza jawne deklarowanie typu "any"
5 "strictNullChecks": true, // Wymusza sprawdzanie wartości null i undefined
6 "strictFunctionTypes": true, // Bardziej rygorystyczne sprawdzanie typów funkcji
7 "strictBindCallApply": true, // Sprawdzanie typów dla metod bind, call i apply
8 "strictPropertyInitialization": true, // Sprawdza, czy właściwości klas są inicjalizowane
9 "noImplicitThis": true, // Wymusza jawne określanie typu "this"
10 "alwaysStrict": true // Parsuje kod w trybie strict mode
11 }
12}W kontekście Parku Jurajskiego:
strict: trueto jak wprowadzenie najwyższego poziomu bezpieczeństwa we wszystkich sektorach parkunoImplicitAnyto jak zasada "zawsze identyfikuj gatunek dinozaura przed umieszczeniem go w zagrodzie"strictNullChecksto jak sprawdzanie, czy ogrodzenia są faktycznie podłączone do prądu, zamiast zakładania, że wszystko działa
Konfiguracja modułów i importów
Zarządzając parkiem, musimy mieć jasny system komunikacji między różnymi działami. W TypeScript konfigurujemy, jak moduły komunikują się ze sobą:
1{
2 "compilerOptions": {
3 "module": "esnext", // System modułów
4 "moduleResolution": "node", // Strategia rozwiązywania modułów
5 "esModuleInterop": true, // Lepsza interoperacyjność z modułami CommonJS
6 "allowSyntheticDefaultImports": true, // Pozwala na import defaultowy z modułów bez eksportu domyślnego
7 "resolveJsonModule": true // Pozwala na import plików JSON
8 }
9}W parku:
moduleResolutionto jak system komunikacji radiowej - określa, jak znajdujemy i kontaktujemy się z różnymi zespołamiesModuleInteropto jak zapewnienie, że starsze i nowsze systemy komunikacji działają razemresolveJsonModuleto jak możliwość odczytywania standardowych formularzy raportów
Opcje developerskie
Dr. Wu potrzebuje narzędzi do tworzenia nowych gatunków dinozaurów. My również potrzebujemy narzędzi developerskich:
1{
2 "compilerOptions": {
3 "sourceMap": true, // Generuje pliki .map dla łatwiejszego debugowania
4 "declaration": true, // Generuje pliki .d.ts z deklaracjami typów
5 "declarationMap": true, // Generuje pliki .map dla plików .d.ts
6 "incremental": true, // Przyspiesza kompilację przez cache poprzednich kompilacji
7 "tsBuildInfoFile": "./dist/.tsbuildinfo" // Plik z informacją o kompilacji
8 }
9}W parku:
sourceMapto jak szczegółowa dokumentacja DNA każdego dinozaura - pomaga zrozumieć, co poszło nie takdeclarationto jak rejestr wszystkich gatunków dinozaurówincrementalto jak optymalizacja procesu klonowania, aby nie powtarzać tych samych procedur
Opcje dla projektów React
Jeśli używasz React (hipotetycznie, interaktywne atrakcje w Parku Jurajskim), przydadzą się dodatkowe opcje:
1{
2 "compilerOptions": {
3 "jsx": "react", // Obsługa składni JSX
4 "jsxFactory": "React.createElement", // Funkcja używana do kompilacji JSX
5 "jsxFragmentFactory": "React.Fragment" // Komponent fragmentu
6 }
7}To jak konfiguracja interaktywnych wyświetlaczy w centrum dla zwiedzających, które pokazują animacje i informacje o dinozaurach.
Konfiguracja dla specyficznych przypadków
Projekt Node.js dla systemu bezpieczeństwa parku
1{
2 "compilerOptions": {
3 "target": "es2018",
4 "module": "commonjs",
5 "outDir": "./dist",
6 "rootDir": "./src",
7 "strict": true,
8 "esModuleInterop": true,
9 "skipLibCheck": true,
10 "forceConsistentCasingInFileNames": true,
11 "lib": ["es2018"]
12 },
13 "include": ["src/**/*"],
14 "exclude": ["node_modules", "**/*.spec.ts"]
15}Aplikacja frontendowa dla dashboard zarządzania parkiem
1{
2 "compilerOptions": {
3 "target": "es5",
4 "lib": ["dom", "dom.iterable", "esnext"],
5 "allowJs": true,
6 "skipLibCheck": true,
7 "esModuleInterop": true,
8 "allowSyntheticDefaultImports": true,
9 "strict": true,
10 "forceConsistentCasingInFileNames": true,
11 "module": "esnext",
12 "moduleResolution": "node",
13 "resolveJsonModule": true,
14 "isolatedModules": true,
15 "noEmit": true,
16 "jsx": "react"
17 },
18 "include": ["src"]
19}Rozszerzanie konfiguracji
W dużym parku dinozaurów mogą istnieć różne strefy z własnymi przepisami bezpieczeństwa, ale wszystkie podlegają ogólnym zasadom. Podobnie, w TypeScript możemy rozszerzać konfiguracje:
1// tsconfig.base.json - główna konfiguracja
2{
3 "compilerOptions": {
4 "target": "es2016",
5 "module": "commonjs",
6 "strict": true
7 }
8}
9
10// tsconfig.backend.json - konfiguracja dla backendu
11{
12 "extends": "./tsconfig.base.json",
13 "compilerOptions": {
14 "outDir": "./dist/backend",
15 "rootDir": "./src/backend"
16 },
17 "include": ["src/backend/**/*"]
18}
19
20// tsconfig.frontend.json - konfiguracja dla frontendu
21{
22 "extends": "./tsconfig.base.json",
23 "compilerOptions": {
24 "outDir": "./dist/frontend",
25 "rootDir": "./src/frontend",
26 "jsx": "react"
27 },
28 "include": ["src/frontend/**/*"]
29}To jak mapa parku z różnymi strefami, które dzielą wspólne zasady bezpieczeństwa, ale mają też własne, specyficzne wytyczne.
Praktyczny przykład: System monitoringu dla Parku Jurajskiego
Wyobraźmy sobie, że tworzymy nowy system monitoringu dla parku, oto jakiej konfiguracji moglibyśmy użyć:
1{
2 "compilerOptions": {
3 // Wersja ES
4 "target": "es2018",
5 "module": "commonjs",
6 "lib": ["es2018", "dom"],
7
8 // Struktura projektu
9 "outDir": "./dist",
10 "rootDir": "./src",
11 "baseUrl": ".",
12 "paths": {
13 "@park/*": ["src/park/*"],
14 "@security/*": ["src/security/*"],
15 "@monitoring/*": ["src/monitoring/*"],
16 "@types/*": ["src/types/*"]
17 },
18
19 // Rygorystyczność
20 "strict": true,
21 "noImplicitAny": true,
22 "strictNullChecks": true,
23
24 // Zarządzanie modułami
25 "moduleResolution": "node",
26 "esModuleInterop": true,
27 "resolveJsonModule": true,
28
29 // Narzędzia developerskie
30 "sourceMap": true,
31 "declaration": true,
32
33 // Dodatkowe reguły
34 "forceConsistentCasingInFileNames": true,
35 "skipLibCheck": true,
36 "noUnusedLocals": true,
37 "noUnusedParameters": true
38 },
39 "include": ["src/**/*"],
40 "exclude": ["node_modules", "dist", "**/*.spec.ts"]
41}Z tym plikiem konfiguracyjnym, nasz system bezpieczeństwa dla Parku Jurajskiego byłby:
- Nowoczesny i kompatybilny z aktualnymi standardami (
es2018) - Dobrze zorganizowany z jasną strukturą katalogów
- Rygorystyczny w sprawdzaniu typów, nie pozwalając na potencjalne luki
- Elastyczny w zarządzaniu modułami i zależnościami
- Łatwy w debugowaniu i z dobrą dokumentacją typów
- Wolny od nieużywanych zmiennych i parametrów, które mogłyby prowadzić do zamieszania
Narzędzia pomocnicze
Poza samym plikiem tsconfig.json, warto również skonfigurować narzędzia pomocnicze, które wspierają pracę z TypeScript:
ESLint dla TypeScript
ESLint to jak dodatkowy system nadzoru w parku, który wyłapuje potencjalne zagrożenia:
1// .eslintrc.json
2{
3 "parser": "@typescript-eslint/parser",
4 "plugins": ["@typescript-eslint"],
5 "extends": [
6 "eslint:recommended",
7 "plugin:@typescript-eslint/recommended"
8 ],
9 "rules": {
10 "no-console": "warn",
11 "@typescript-eslint/explicit-function-return-type": "error",
12 "@typescript-eslint/no-explicit-any": "error"
13 }
14}Prettier dla formatowania kodu
Prettier to jak standard ubierania się i zachowania dla pracowników parku - wszyscy wyglądają i działają spójnie:
1// .prettierrc
2{
3 "semi": true,
4 "trailingComma": "all",
5 "singleQuote": true,
6 "printWidth": 100,
7 "tabWidth": 2
8}Typowe problemy i rozwiązania
Problem: "Property 'x' does not exist on type 'y'"
Ten błąd to jak system bezpieczeństwa alarmujący, że próbujesz użyć nieistniejącego kodu dostępu do zagrody:
1// Błąd
2const dino = { gatunek: "T-Rex", wiek: 5 };
3console.log(dino.wysokosc); // Error: Property 'wysokosc' does not exist on type '{ gatunek: string; wiek: number; }'.
4
5// Rozwiązanie 1: Dodaj właściwość do typu
6const dino: { gatunek: string; wiek: number; wysokosc?: number } = {
7 gatunek: "T-Rex",
8 wiek: 5
9};
10
11// Rozwiązanie 2: Użyj interfejsu
12interface Dinozaur {
13 gatunek: string;
14 wiek: number;
15 wysokosc?: number;
16}
17const dino: Dinozaur = { gatunek: "T-Rex", wiek: 5 };Problem: Konfiguracja nie jest stosowana
Czasem, podobnie jak w parku gdy system bezpieczeństwa nie reaguje, konfiguracja TypeScript może nie być właściwie stosowana:
- Sprawdź, czy ścieżki w
includeiexcludesą poprawne - Upewnij się, że używasz odpowiedniego pliku tsconfig.json
- Zrestartuj serwer TypeScript w swoim IDE
1# Sprawdź, które pliki są przetwarzane przez TypeScript
2tsc --listFiles
3
4# Sprawdź, czy kompilator znajduje plik tsconfig.json
5tsc --showConfigProblem: Brak typów dla biblioteki zewnętrznej
To jak odkrycie, że brakuje dokumentacji dla nowego sprzętu bezpieczeństwa w parku:
1# Spróbuj znaleźć definicje typów dla biblioteki
2npm install --save-dev @types/nazwa-biblioteki
3
4# Jeśli nie istnieją oficjalne typy, stwórz własne
5touch src/types/nazwa-biblioteki.d.ts1// src/types/nazwa-biblioteki.d.ts
2declare module 'nazwa-biblioteki' {
3 export function funkcja1(param: string): number;
4 export function funkcja2(param: number): string;
5 export const stala: string;
6}Podsumowanie
Plik tsconfig.json jest jak mapa Parku Jurajskiego - definiuje strefy, poziomy bezpieczeństwa i wytyczne dla wszystkich systemów. Odpowiednia konfiguracja TypeScript zapewnia:
- Spójny kod w całym projekcie
- Wykrywanie potencjalnych problemów na wczesnym etapie
- Lepsze wsparcie narzędzi developerskich
- Jasne reguły dla całego zespołu programistów
Tak jak John Hammond nie szczędził kosztów na zabezpieczenia parku, tak i my nie powinniśmy pomijać odpowiedniej konfiguracji TypeScript. To inwestycja, która zwraca się w postaci bardziej stabilnego i bezpiecznego kodu.
W następnej lekcji przyjrzymy się kompilatorowi TypeScript i dowiemy się, jak przekształca on kod TypeScript w JavaScript, podobnie jak naukowcy w laboratorium przekształcają DNA w żywe dinozaury!
Kod do tej lekcji: tsconfig.json
1{
2 "compilerOptions": {
3 /* Language and Environment */
4 "target": "ES2020",
5 "lib": ["ES2020", "DOM"],
6 "module": "commonjs",
7 "moduleResolution": "node",
8
9 /* Output */
10 "outDir": "./dist",
11 "rootDir": "./src",
12 "removeComments": true,
13 "sourceMap": true,
14
15 /* Type Checking */
16 "strict": true,
17 "noImplicitAny": true,
18 "strictNullChecks": true,
19 "strictFunctionTypes": true,
20 "noUnusedLocals": true,
21 "noUnusedParameters": true,
22 "noImplicitReturns": true,
23
24 /* Interop Constraints */
25 "esModuleInterop": true,
26 "allowSyntheticDefaultImports": true,
27 "forceConsistentCasingInFileNames": true,
28
29 /* Skip Library Check */
30 "skipLibCheck": true
31 },
32 "include": ["src/**/*"],
33 "exclude": ["node_modules", "dist", "**/*.spec.ts"]
34}Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Co określa opcja 'target' w pliku tsconfig.json?
2. Do czego służą opcje 'include' i 'exclude' w tsconfig.json?
Zadania praktyczne w grze
- Edytor kodu
Uzupełnij plik tsconfig.json z opcjami strict, target i outDir.