Strona główna / Artykuły / Podstawa React gotowa do użycia w produkcji: co faktycznie robi każdy pakiet.

Podstawa React gotowa do użycia w produkcji: co faktycznie robi każdy pakiet.

Ustaw Vite, Tailwind v4, Redux Toolkit, React Router, Jest i Prettier dla aplikacji React oraz zrozum, dlaczego każdy pakiet i linia konfiguracji jest tam obecna.

3165 słów

Wykonanie polecenia npm create vite daje aplikację React, która się renderuje, ale nie jest to rozwiązanie przeznaczone dla prawdziwych użytkowników: brakuje systemu stylizacji, wspólnego stanu, routingu, testów oraz ustalonego formatu kodu. Ten przewodnik krok po kroku buduje te brakujące elementy za pomocą Tailwind CSS, Redux Toolkit, React Router, Jest w połączeniu z React Testing Library oraz Prettier. Dla każdego pakietu odpowiada na dwa pytania: co on faktycznie robi i co się zepsuje, jeśli go pominąć? Pod koniec będziesz miał gotową bazę do rozwijania nowych funkcjonalności, a co równie ważne – będziesz w stanie czytać swój własny plik package.json i wyjaśniać każdą linię.

Zestaw narzędzi w pigułce:

  • Tailwind CSS do stylizacji
  • Redux Toolkit do zarządzania wspólnymi danymi aplikacji
  • React Router do nawigacji między stronami
  • Jest, React Testing Library oraz niewielki zestaw narzędzi Babel, aby testy w ogóle mogły działać
  • Prettier, dzięki któremu formatowanie przestaje być kwestią subiektywną
  • Część z tych narzędzi można zainstalować w jednej linii. Inne kryją zaskakujące szczegóły; na przykład „React Testing Library” to w rzeczywistości trzy pakiety pełniące trzy różne funkcje.

    Zacznij od nowego projektu Vite przy użyciu szablonu React + TypeScript:

    npm create vite@latest react-production-stack -- --template react-ts
    cd react-production-stack
    npm install
    

    Tailwind CSS: stylizacja wprowadzana od razu

    Pakiety: tailwindcss, @tailwindcss/vite

    Stylizacja dotyczy każdego komponentu, więc sensowne jest sprawdzenie jej działania przed dodaniem czegokolwiek innego.

    npm install tailwindcss @tailwindcss/vite
    

    To instaluje oba pakiety jako zwykłe zależności, a nie devDependencies. Mówiąc ściśle, żaden z pakietów nie działa w przeglądarce: plugin Vite wykonywa swoje zadania podczas budowania, a do pliku końcowego trafia jedynie wygenerowany CSS. Dlatego wiele zespołów umieszcza je w kategorii devDependencies, a przy aplikacji jednostronicowej spakowanej w jeden plik obie opcje dają ten sam wynik. Wybierz jedną konwencję i trzymaj się jej konsekwentnie.

    Następnie zarejestruj plugin obok pluginu React w konfiguracji Vite:

    import { defineConfig } from 'vite'
    import react from '@vitejs/plugin-react'
    import tailwindcss from '@tailwindcss/vite'
    
    export default defineConfig({
      plugins: [react(), tailwindcss()],
    })
    

    Potem zastąp zawartość src/index.css jednym importem. Oto cały plik:

    /* Tailwind v4 is CSS-first. No config file, no content globs. */
    @import 'tailwindcss';
    

    To naprawdę wszystko, co potrzeba do konfiguracji. Tailwind v4 opiera się na CSS: nie ma pliku tailwind.config.js ani listy globalnych nazw elementów, ponieważ sam analizuje pliki źródłowe w poszukiwaniu nazw klas.

    Weryfikacja działania

    Tymczasowo dodaj kilka klas pomocniczych do nagłówka w pliku App.tsx, na przykład text-3xl font-bold text-blue-600, uruchom npm run dev i sprawdź, czy nagłówek się zmieni. Jeśli tak, oznacza to, że wtyczka i import CSS są połączone.

    Dlaczego klasy pomocnicze zamiast oddzielnych plików stylów

    Tailwind przechowuje style bezpośrednio w elementach, na które mają wpływ. W przypadku oddzielnego pliku CSS łatwo jest edytować komponent, a potem zapomnieć o jego pliku stylów, co powoli prowadzi do gromadzenia się niepotrzebnych i przestarzałych reguł. Szczególnie panele kontrolne wielokrotnie używają tych samych elementów (karty, odznaki, przyciski), a budowanie ich z jednego wspólnego zestawu klas pomocniczych zapewnia spójność wizualną przy mniejszej ilości kodu do utrzymania. Kompromisem jest zmiana nawyków: zamiast wymyślać nazwy klas takie jak .card-header-active, każdy element składa się z małych, z góry zdefiniowanych klas.

    Redux Toolkit: magazyn danych i most do React

    Pakiety: @reduxjs/toolkit, react-redux

    Te dwa pakiety łatwo pomieszać, ale pełnią różne funkcje:

    • @reduxjs/toolkit to sam magazyn danych: przechowuje dane aplikacji i wprowadza w nich aktualizacje.
    • react-redux to połączenie z React: dostarcza komponent <Provider> oraz hooki, których używają komponenty do odczytywania i aktualizowania tych danych.

    Potrzebujesz obu, ponieważ żaden z nich nie może wykonać zadania drugiego.

    npm install @reduxjs/toolkit react-redux
    

    Stwórz magazyn danych w pliku src/app/store.ts. Zaczyna się on od pustego mapy reduktorów i eksportuje dwa typy pochodzące z magazynu, aby reszta aplikacji nie musiała ich ręcznie definiować:

    import { configureStore } from '@reduxjs/toolkit'
    
    export const store = configureStore({
      reducer: {},
    })
    
    export type RootState = ReturnType<typeof store.getState>
    export type AppDispatch = typeof store.dispatch
    

    Obiekt reducer: {} na razie pozostaje pusty. Dodawane są tylko fragmenty danych, gdy pojawią się rzeczywiste funkcje, takie jak projekty czy zadania; nie ma sensu tworzyć stanu przed tym, zanim jakikolwiek ekran go wykorzysta.

    Następnie definiuje się typowane hooki w pliku src/app/hooks.ts. Narzędzia withTypes, dostępne w najnowszych wersjach React Redux, łączą useDispatch i useSelector z typami sklepu tylko raz, dzięki czemu komponenty uzyskują pełną inferencję typów bez konieczności adnotowania każdej wywołania:

    import { useDispatch, useSelector } from 'react-redux'
    import type { AppDispatch, RootState } from './store'
    
    export const useAppDispatch = useDispatch.withTypes<AppDispatch>()
    export const useAppSelector = useSelector.withTypes<RootState>()
    

    Dostarczanie sklepu do drzewa komponentów

    W tym momencie sklep już istnieje, ale React o nim nie wie. <Provider> umożliwia dostęp do niego każdemu komponentowi znajdującemu się poniżej, dlatego umieszcza się go na samym szczycie drzewa w pliku src/main.tsx:

    import { StrictMode } from 'react'
    import { createRoot } from 'react-dom/client'
    import { Provider } from 'react-redux'
    import { store } from './app/store'
    import App from './App'
    import './index.css'
    
    createRoot(document.getElementById('root')!).render(
      <StrictMode>
        <Provider store={store}>
          <App />
        </Provider>
      </StrictMode>,
    )
    

    Wszystko, co jest renderowane wewnątrz <Provider>, może teraz wywoływać funkcje useAppSelector i useAppDispatch.

    Weryfikacja poprawności działania

    Zainstaluj aplikację i upewnij się, że strona nadal jest renderowana bez błędu "could not find react-redux context". Ten błąd pojawia się wtedy, gdy komponent używa hooków Redux poza kontekstem Provider. Przy pustym sklepie nie ma jeszcze nic więcej do sprawdzenia.

    Kiedy używać Redux, a kiedy wystarczy useState

    Nie wszystko powinno znajdować się w Redux – przechowywanie całego stanu w sklepie jest równie błędne jak trzymanie wszystkiego lokalnie. Praktyczna zasada ogólna:

    • useState do danych istotnych dla pojedynczego ekranu lub komponentu: czy modala jest otwarta, aktualna wartość pola wprowadzania danych, wybrana opcja w menu rozwijanym.
  • Redux służy do przechowywania danych potrzebnych jednocześnie na kilku ekranach lub komponentach, takich jak lista zadań pokazywana na wielu stronach lub pojedyncze zadanie widoczne na panelu sterowania, liście zadań oraz w szczegółowym widoku zadania.
  • Jeśli jakaś informacja o stanie musiałaby być przekazywana przez kilka warstw lub kopiowana między ekranami, to jest to dobry znak, że powinna znajdować się w sklepie danych (store).

    React Router: routowanie przed pierwszą rzeczywistą stroną

    Pakiet: react-router

    Dodawanie mechanizmu routowania przed utworzeniem jakiejkolwiek rzeczywistej strony może wydawać się przedwczesne, ale szybko przynosi korzyści: każdy nowy ekran staje się dodatkowym elementem <Route>, zamiast wymagać późniejszej rekonstrukcji aplikacji.

    npm install react-router
    

    Umieść tabelę tras w osobnym module, src/routes/AppRoutes.tsx. Na razie mapuje ona / na komponent zastępczy ukształtowany za pomocą narzędzi Tailwind:

    import { Route, Routes } from 'react-router'
    
    function Placeholder() {
      return (
        <div className="flex min-h-screen items-center justify-center">
          <p className="text-slate-600">Routes coming soon</p>
        </div>
      )
    }
    
    export function AppRoutes() {
      return (
        <Routes>
          <Route path="/" element={<Placeholder />} />
        </Routes>
      )
    }
    

    src/App.tsx następnie po prostu renderuje tę tabelę tras:

    import { AppRoutes } from './routes/AppRoutes'
    
    function App() {
      return <AppRoutes />
    }
    
    export default App
    

    Na koniec otocz aplikację tagiem <BrowserRouter> w pliku src/main.tsx, obok dostawcy Redux:

    import { StrictMode } from 'react'
    import { createRoot } from 'react-dom/client'
    import { Provider } from 'react-redux'
    import { BrowserRouter } from 'react-router'
    import { store } from './app/store'
    import App from './App'
    import './index.css'
    
    createRoot(document.getElementById('root')!).render(
      <StrictMode>
        <Provider store={store}>
          <BrowserRouter>
            <App />
          </BrowserRouter>
        </Provider>
      </StrictMode>,
    )
    

    Wynikowa łańcuchowa struktura to main.tsx<App /><AppRoutes /> → ten element <Route>, który pasuje do adresu URL. Redux i router są niezależne, więc kolejność ich umieszczania nie ma znaczenia; jedynym wymogiem jest to, aby oba otaczały element <App>.

    Weryfikacja poprawności działania

    Zainstaluj npm run dev i otwórz katalog /. Jeśli pojawi się tekst zastępczy, <BrowserRouter>, <Routes> oraz <Route> są poprawnie skonfigurowane.

    Jest i React Testing Library: cztery zadania, jedenaście pakietów

    Pakiety: jest, @testing-library/react, babel-jest oraz kilka innych

    To jest etap, który zajmuje najwięcej czasu. Sami koncepcje nie są trudne, ale „dodanie testów” oznacza w praktyce instalację około jedenaście pakietów, które obejmują cztery różne funkcje, a następnie sprawdzenie, czy jeden test przejdzie przy użyciu routera. Grupowanie pakietów według zadań znacznie ułatwia zrozumienie całego procesu.

    Grupa A: narzędzie do wykonywania testów i symulowany przeglądarka

    npm install -D jest jest-environment-jsdom
    
    • jest jest narzędziem do wykonywania testów. Odnajduje pliki *.test.tsx, je wykonywa i raportuje wyniki pozytywne oraz negatywne. Nic innego w tej sekcji nie funkcjonuje bez niego.
    • jest-environment-jsdom jest konieczny, ponieważ Jest działa w Node, gdzie nie istnieje zmienna document. Dostarcza symulowany DOM, dzięki czemu komponenty mają gdzie się renderować.

    Grupa B: React Testing Library składa się z trzech pakietów

    npm install -D @testing-library/react
    npm install -D @testing-library/jest-dom
    npm install -D @testing-library/user-event
    

    To, co ludzie nazywają „React Testing Library”, to w rzeczywistości trzy biblioteki, z których każda pełni swoją rolę:

    • @testing-library/react renderuje komponent na symulowanej stronie i dostarcza funkcje do wyszukiwania, takie jak screen.getByText(...).
  • @testing-library/jest-dom dodaje czytelne narzędzia do porównywania, takie jak toBeInTheDocument(), dzięki czemu nie musisz ręcznie porównywać wyników zapytań z wartością null.
  • @testing-library/user-event symuluje realistyczne zachowanie użytkownika. Pisanie tekstu wywołuje pełną sekwencję skupienia uwagi, naciśnięcia klawisza, wprowadzania danych i zwolnienia klawisza, taką jak w przeglądarce, zamiast pojedynczego syntetycznego zdarzenia wysyłanego do elementu.
  • Krótko mówiąc: renderuj, sprawdzaj, wchodź w interakcję. Trzy zadania, trzy pakiety – i prawie zawsze chcesz je wszystkie.

    Grupa C: zestaw narzędzi Babel umożliwiający Jestowi obsługę plików TSX

    Grupa ta istnieje z jednego powodu: Jest sam nie potrafi zrozumieć plików TypeScript ani JSX.

    • babel-jest łączy te dwa elementy. Jest przekazuje każdy plik przez Babel przed jego wykonaniem.
    • @babel/preset-typescript usuwa adnotacje typów. Nie sprawdza nic pod kątem typów; po prostu usuwa : string oraz podobne składnię.
    • @babel/preset-react kompiluje JSX w zwykłe wywołania funkcji.
    • @babel/preset-env przekształca nowoczesną składnię w tę, którą obsługuje Twoja wersja Node.

    W odróżnieniu od grupy B, należy je zainstalować razem w jednym poleceniu. Wszystkie te presety wymagają kompatybilnego @babel/core, a ich instalacja po częściach w projekcie, który już zawiera Jest (który ładuje własne zależności Babel), może spowodować, że npm będzie próbował pogodzić niezgodne wersje. Jednym z objawów jest błąd ERESOLVE unable to resolve dependency tree podczas kolejnej instalacji pojedynczego pakietu. Instalacja całej grupy jednocześnie pozwala npm na rozwiązanie tego problemu poprzez użycie spójnego zestawu wersji.

    Kolejna, bardziej subtelna pułapka wynika z kopiowania długich poleceń z plików PDF lub stron internetowych. Tekst z formatowaniem typu soft-wrap może po wklejeniu zamienić się w rzeczywiste przerwy wierszy, przez co nazwa pakietu taka jak @babel/preset-typescript zostaje podzielona na dwie części, a shell uruchamia drugą część jako oddzielne, bezsensowne polecenie. Wyraźne kontynuacje wierszy umożliwiają umieszczenie przerw dokładnie tam, gdzie tego chcemy. Poniżej przedstawiono składnię Windows Command Prompt:

    npm install -D babel-jest ^
      @babel/core ^
      @babel/preset-env ^
      @babel/preset-react ^
      @babel/preset-typescript
    

    Symbol ^ na końcu informuje cmd.exe, że polecenie kontynuuje się na następnym wierszu. W PowerShell symbolem kontynuacji jest cudzysłów odwrócony, a w bash lub zsh to ukośnik odwrotny. Niezależnie od używanego shella, nadal jest to dokładnie jedno polecenie npm install.

    Grupa D: typy tylko dla twojego edytora

    npm install -D @types/jest
    

    Ten pakiet nie ma wpływu na sposób wykonywania testów; Babel usunął już wtedy wszystkie typy. Istnieje po to, aby TypeScript i Twój edytor rozpoznawały globalne funkcje takie jak test(...) i expect(...), zamiast sygnalizować je jako błędy.

    Dodawanie skryptów testowych

    Instalacja Jest nie dostarcza polecenia npm test, więc musisz sam dodać te skrypty do pliku package.json:

    "scripts": {
      "dev": "vite",
      "build": "tsc -b && vite build",
      "lint": "eslint .",
      "test": "jest",
      "test:watch": "jest --watch"
    }
    

    npm test uruchamia cały zestaw testów raz. npm run test:watch pozostaje w tle i uruchamia ponownie tylko te testy, które zostały zmienione w pliku, który właśnie zapisałeś; miej go otwarty w drugim terminalu podczas pracy.

    Warto zapamiętać jeszcze dwa polecenia na wypadek problemów:

    npx jest src/App.test.tsx   # run one file only
    npx jest --clearCache       # when Jest keeps showing an error
                                # you already fixed
    

    Polecenie cache ma większe znaczenie, niż się wydaje. Jest przechowuje przetworzone pliki, więc po zmianie pliku babel.config.cjs lub jest.config.cjs może nadal serwować stary wynik i zgłaszać błąd, który już naprawiłeś. Gdy wydaje się, że naprawa nie działa, usuń cache, zanim doszedniesz do wniosku, że naprawa jest błędna.

    Pełna konfiguracja testów

    Poniżej znajdują się wszystkie pliki konfiguracyjne w całości, wraz z wyjaśnieniem tego, za co jest odpowiedzialny każdy z nich.

    babel.config.cjs

    Ustawienia domyślne są identyczne z grupą C: celują w aktualną wersję Node, wykorzystują automatyczny silnik JSX, dzięki czemu pliki nie muszą importować React, oraz usuwają TypeScript. Wbudowany plugin radzi sobie z czymś, czego nie potrafi Jest: import.meta, który jest używany w kodzie Vite do celów takich jak import.meta.env i gorąca zamiana modułów, ale który nie jest ważny w formacie CommonJS używanym przez Jest.

    function stripImportMeta() {
      return {
        visitor: {
          MetaProperty(path) {
            path.replaceWithSourceString('({ url: "", hot: undefined })')
          },
        },
      }
    }
    
    module.exports = {
      presets: [
        ['@babel/preset-env', { targets: { node: 'current' } }],
        ['@babel/preset-react', { runtime: 'automatic' }],
        '@babel/preset-typescript',
      ],
      plugins: [stripImportMeta],
    }
    

    To jest prawdziwy plugin Babel, napisany jako funkcja wewnątrz kodu zamiast jako zainstalowany pakiet; Babel akceptuje obie formy. MetaProperty to typ węzła AST używany przez Babel dla import.meta, a mechanizm przeglądania zastępuje każdą jego wystąpienie zwykłym obiektem, który ma pusty polu url oraz niezdefiniowane pole hot. Należy pamiętać, że to również ukrywa wszystkie wartości z import.meta.env przed testowanym kodem, więc komponenty, które odczytują zmienne środowiskowe, będą wymagać ich symulacji osobno.

    jest.config.cjs

    To plik łączący narzędzie uruchamiania z całym resztą. Wybiera środowisko jsdom, ładuje plik konfiguracyjny po przygotowaniu środowiska, przekazuje każdy plik JavaScript i TypeScript przez babel-jest, a także mapuje importy stylów i obrazów na moduły zastępcze.

    module.exports = {
      testEnvironment: 'jsdom',
      setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
      moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'mjs', 'json'],
      transform: {
        '^.+\\.(ts|tsx|js|jsx|mjs)
    : 'babel-jest', }, transformIgnorePatterns: ['node_modules/(?!(react-router|cookie-es)/)'], moduleNameMapper: { '\\.(css|less|scss|sass)
    : '<rootDir>/test/styleMock.js', '\\.(png|jpg|jpeg|gif|svg|webp)
    : '<rootDir>/test/fileMock.js', }, }

    Warto zwrócić uwagę na element transformIgnorePatterns. Domyślnie Jest nie przetwarza niczego w katalogu node_modules. Negatywny wzorzec wyszukiwania stanowi wyjątek dla bibliotek react-router i cookie-es, które są publikowane jako moduły ES, których pipeline CommonJS w Jest nie może załadować bez przetworzenia. Jeśli później dodasz kolejną zależność dostępną tylko w formacie ESM i pojawi się błąd SyntaxError: Cannot use import statement outside a module, to właśnie do tego wzorca należy ją dodać.

    jest.setup.ts

    Plik konfiguracyjny rejestruje matcherzy jest-dom oraz dodaje klasy TextEncoder i TextDecoder do globalnego zakresu dostępu. Środowisko jsdom ich nie udostępnia, natomiast React Router oczekuje, że istnieją, dlatego są one pożyczane z modułu node:util w Node.js:

    import { TextEncoder, TextDecoder } from 'node:util'
    import '@testing-library/jest-dom'
    
    Object.assign(globalThis, { TextEncoder, TextDecoder })
    

    Styl i mocki plików

    Jest nie ma pojęcia, jak importować plik CSS lub PNG. Poniższe dwa moduły tymczasowe są miejscem, do którego moduleNameMapper kieruje te importy, dzięki czemu komponent zawierający import './App.css' nie powoduje awarii podczas wykonywania testu:

    // test/styleMock.js
    module.exports = {}
    
    // test/fileMock.js
    module.exports = 'test-file-stub'
    

    src/App.test.tsx

    Na koniec test, który sprawdza całą konfigurację. Wyświetla App wewnątrz MemoryRouter, który przechowuje stan routingu w pamięci zamiast czytać rzeczywisty adres URL przeglądarki, i sprawdza, czy obecny jest tekst zastępczy:

    import { render, screen } from '@testing-library/react'
    import { MemoryRouter } from 'react-router'
    import App from './App'
    
    test('renders the placeholder route content', () => {
      render(
        <MemoryRouter>
          <App />
        </MemoryRouter>,
      )
      expect(screen.getByText(/routes coming soon/i)).toBeInTheDocument()
    })
    

    Mimo swojej małości, ten test obejmuje każdy element architektury: kompilację TSX, pakiet routera ESM, polyfilli do kodowania tekstu, obsługę import.meta oraz matchera jest-dom. Jeśli test przejdzie, konfiguracja jest poprawna.

    Prettier: zakończenie debat o formatowaniu

    Pakiety: prettier, eslint-config-prettier

    npm install -D prettier eslint-config-prettier
    
    • prettier przekształca twój kod w spójny styl, zwykle po zapisaniu pliku.
    • eslint-config-prettier ma jeden precyzyjny cel: wyłącza zasady ESLint, które kolidują z formatowaniem Prettiera, takie jak zasady dotyczące cudzysławów, średników i przecinków końcowych.

    Drugi pakiet nie dodaje żadnych własnych zasad; jedynie zapobiega konfliktom pomiędzy tymi dwoma narzędziami. W pliku eslint.config.js musi być to ostatnia pozycja w liście konfiguracji, ponieważ późniejsze pozycje przykrywają te wcześniejsze, a on musi przykryć je, zamiast być przez nie przykryty.

    Dlaczego warto dodać ten dodatkowy pakiet

    Bez automatycznego formatowania czas przeglądania przechyla się ku użyciu tabulacji zamiast spacji, zamiast kierować się logiką. Prettier celowo oferuje tylko kilka opcji, dzięki czemu nie ma już wiele tematów do dyskusji, i to właśnie jest sedno sprawy.

    Łączenie wszystkiego razem

    Pozostaje jedna luka. tsc -b sprawdza typy wszystkiego znajdującego się pod katalogiem src, włączając pliki testowe, ale domyślnie nie wie nic o plikach test ani expect. Należy dodać odpowiednie pakiety typów do tablicy types w pliku tsconfig.app.json:

    "types": ["vite/client", "jest", "@testing-library/jest-dom"]
    

    Następnie należy uruchomić pełną sekwencję weryfikacji, zaczynając od najtańszego kroku:

    npm run lint    # fast, catches obvious mistakes
    npm test        # fast, catches broken behaviour
    npm run build   # slower — real compile, real Tailwind output
    npm run dev     # slowest — but the only one that proves it renders
    

    Linting odbywa się szybko i wykrywa oczywiste błędy, testy potwierdzają zachowanie aplikacji, proces budowania przeprowadza rzeczywiste skompilowanie i generuje faktyczny plik Tailwind, natomiast serwer deweloperski, który jest najwolniejszą czynnością sprawdzającą, jest jedynym narzędziem potwierdzającym, że aplikacja renderuje się w przeglądarce. Gdy wszystkie cztery kroki przejdą pomyślnie, fundamenty aplikacji są gotowe, bez ani jednej linii kodu funkcjonalnego.

    Uwaga na temat alternatyw

    Znaczna część sekcji Jest (przeddefiniowane ustawienia Babel, wtyczka import.meta, wyjątki ESM) istnieje dlatego, że Jest nie korzysta z pipeline’a budowania Vite. Jeśli wolisz mniej elementów, które mogą powodować problemy, Vitest wykorzystuje twoją konfigurację Vite i działa z tymi samymi pakietami Testing Library. Aby poznać inne sposoby ograniczenia narzędzi testowych, sprawdź naszy przewodnik dotyczący zastąpienia Jest narodowym wykonywaczem testów w Node. Powyższa konfiguracja Jest pozostaje solidnym wyborem, gdy twój zespół już zna Jest lub polega na jego ekosystemie.

    Główne wnioski

    • Traktuj każdą zależność jako decyzję: wiedz, co robi i co się psuje bez niej.
    • Tailwind v4 wymaga jedynie wtyczki Vite oraz jednego importu CSS; nie jest potrzebny żaden plik konfiguracyjny.
  • Redux Toolkit przechowuje dane, a React Redux łączy je z komponentami; typowane hooki zapewniają czystość kodu, a lokalny stan interfejsu użytkownika powinien nadal znajdować się w useState.
  • Dodanie routera na wczesnym etapie sprawia, że każda przyszła strona wymaga tylko jednej zmiany.
  • Jest w projekcie Vite wymaga runnera, środowiska DOM, trzech pakietów z Testing Library, zestawu narzędzi Babel oraz kilku precyzyjnych korekt konfiguracji; jeśli jakieś poprawki wydają się ignorowane, należy wyczyścić cache Jest.
  • Zainstaluj pakety wzajemnie zależne za pomocą jednego polecenia i używaj wyraźnych kontynuacji wierszy, gdy polecenie sięga kilku wierszy.
  • Literatura pokrewna