Kurs JavaScript i React · Moduł 1: Podstawy React
Tworzenie projektu React z Vite
W tej lekcji6
W kosmicznej podróży przez świat React potrzebujesz odpowiedniego statku, aby wyruszyć w drogę. Dawniej standardowym wyborem był Create React App (CRA), ale to narzędzie zostało oficjalnie wycofane (deprecated) i nie jest już rozwijane. Współczesnym standardem do tworzenia projektów React jest Vite - ultraszybki bundler nowej generacji.
Ra, nasz kosmiczny przewodnik, mówi: "Porzuć stary wahadłowiec CRA - Vite to nowy napęd warp, który przeniesie Cię w galaktykę React szybciej niż kiedykolwiek!"
Dlaczego Vite?
Vite (wymawiane "vit", z francuskiego "szybki") to nowoczesne narzędzie do budowania aplikacji frontendowych, stworzone przez Evana You (twórcę Vue.js). Dokumentacja React wymienia je (obok Parcel i Rsbuild) wśród zalecanych narzędzi, gdy budujesz aplikację bez frameworka.
Dlaczego Vite zastąpił CRA:
- Błyskawiczny start serwera - Vite wykorzystuje natywne moduły ES (ESM) przeglądarki, więc serwer deweloperski startuje w 1-2 sekundy (CRA potrzebował 20-40 sekund)
- Natychmiastowy Hot Module Replacement (HMR) - zmiany w kodzie pojawiają się w przeglądarce w ~50ms, niezależnie od rozmiaru aplikacji
- Nowoczesna architektura - oparty na ESM zamiast starszego Webpacka
- Szybkie buildy produkcyjne - od Vite 8 wykorzystuje Rolldown (wcześniej Rollup) do łączenia plików w paczki
- Wsparcie od razu po instalacji - TypeScript, JSX, CSS Modules, PostCSS działają bez dodatkowej konfiguracji
Tworzenie nowego projektu z Vite
Aby utworzyć nowy projekt React z Vite, otwórz terminal i wpisz:
1npm create vite@latest moja-aplikacja-react -- --template reactTo polecenie:
- Używa
npm createdo uruchomienia generatora Vite vite@latestzapewnia użycie najnowszej wersjimoja-aplikacja-reactto nazwa Twojego projektu--template reactwybiera szablon React (dostępne też:react-tsdla TypeScript)
Po utworzeniu projektu przejdź do katalogu i zainstaluj zależności:
1cd moja-aplikacja-react
2npm installNastępnie uruchom serwer deweloperski:
1npm run devTwoja aplikacja będzie dostępna pod adresem http://localhost:5173 w przeglądarce. Zwróć uwagę - Vite domyślnie używa portu 5173, nie 3000.
Struktura projektu Vite + React
Po utworzeniu projektu zobaczysz następującą strukturę:
1moja-aplikacja-react/
2├── node_modules/ # Zainstalowane zależności
3├── public/ # Pliki statyczne (kopiowane bez zmian)
4│ ├── favicon.svg # Ikona strony
5│ └── icons.svg # Ikony
6├── src/ # Kod źródłowy
7│ ├── assets/ # Zasoby (obrazy, fonty)
8│ │ └── react.svg # Logo React
9│ ├── App.css # Style komponentu App
10│ ├── App.jsx # Główny komponent App
11│ ├── index.css # Globalne style
12│ └── main.jsx # Punkt wejściowy aplikacji
13├── index.html # Główny plik HTML (w katalogu głównym!)
14├── vite.config.js # Konfiguracja Vite
15├── package.json # Informacje o projekcie i zależności
16├── .gitignore # Pliki ignorowane przez Git
17└── .oxlintrc.json # Konfiguracja lintera (Oxlint)Kluczowe różnice w stosunku do CRA
Zauważ kilka istotnych różnic:
- index.html jest w katalogu głównym, nie w
public/- Vite traktuje go jako punkt wejściowy - Pliki używają rozszerzenia .jsx zamiast .js - to jasny sygnał, że plik zawiera JSX
- Punkt wejściowy to main.jsx, nie index.js
- vite.config.js zamiast ukrytej konfiguracji Webpacka - masz pełną kontrolę
index.html
W Vite plik index.html jest w katalogu głównym projektu i wygląda tak:
1<!DOCTYPE html>
2<html lang="en">
3 <head>
4 <meta charset="UTF-8" />
5 <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 <title>Vite + React</title>
8 </head>
9 <body>
10 <div id="root"></div>
11 <script type="module" src="/src/main.jsx"></script>
12 </body>
13</html>Kluczowa linia to <script type="module" src="/src/main.jsx"></script> - Vite ładuje aplikację jako natywny moduł ES, co zapewnia błyskawiczny start.
src/main.jsx
To punkt wejściowy aplikacji React:
1import React from 'react'
2import ReactDOM from 'react-dom/client'
3import App from './App.jsx'
4import './index.css'
5
6ReactDOM.createRoot(document.getElementById('root')).render(
7 <React.StrictMode>
8 <App />
9 </React.StrictMode>,
10)Ten kod:
- Importuje React i ReactDOM
- Tworzy "korzeń" React w elemencie o id
root - Renderuje główny komponent
AppwewnątrzStrictMode
src/App.jsx
Główny komponent Twojej aplikacji:
1import { useState } from 'react'
2import reactLogo from './assets/react.svg'
3import viteLogo from '/vite.svg'
4import './App.css'
5
6function App() {
7 const [count, setCount] = useState(0)
8
9 return (
10 <>
11 <div>
12 <a href="https://vite.dev" target="_blank">
13 <img src={viteLogo} className="logo" alt="Vite logo" />
14 </a>
15 <a href="https://react.dev" target="_blank">
16 <img src={reactLogo} className="logo react" alt="React logo" />
17 </a>
18 </div>
19 <h1>Vite + React</h1>
20 <div className="card">
21 <button onClick={() => setCount(c => c + 1)}>
22 count is {count}
23 </button>
24 </div>
25 </>
26 )
27}
28
29export default Appvite.config.js
Plik konfiguracyjny Vite - prosty i czytelny:
1import { defineConfig } from 'vite'
2import react from '@vitejs/plugin-react'
3
4export default defineConfig({
5 plugins: [react()],
6})To wszystko, czego potrzeba! Plugin @vitejs/plugin-react zapewnia wsparcie JSX, Fast Refresh (HMR) i inne funkcje React.
Dostępne skrypty
W package.json projektu Vite znajdziesz:
npm run dev- uruchamia serwer deweloperski z HMRnpm run build- buduje aplikację do wdrożenia produkcyjnegonpm run preview- podgląd zbudowanej wersji produkcyjnej lokalnienpm run lint- sprawdza kod linterem (w aktualnym szablonie: Oxlint)
Vite vs CRA - porównanie
| Cecha | CRA (wycofane) | Vite |
|---|---|---|
| Status | Wycofane, brak aktualizacji | Aktywnie rozwijane |
| Start serwera | 20-40 sekund | 1-2 sekundy |
| HMR | 1-3 sekundy | ~50ms |
| Bundler | Webpack | Rolldown (od Vite 8; wcześniej esbuild + Rollup) |
| Konfiguracja | Ukryta (eject) | Jawna (vite.config.js) |
| Moduły | CommonJS | Natywne ES Modules |
| TypeScript | Wymaga konfiguracji | Działa od razu |
Inne narzędzia w ekosystemie React
Oprócz Vite, warto znać inne popularne narzędzia:
- Next.js - framework React z SSR (Server-Side Rendering), SSG i routingiem opartym na plikach. Idealny do aplikacji wymagających SEO
- React Router (dawniej Remix) - framework React skupiony na podstawach sieci i stopniowym ulepszaniu (progressive enhancement)
- Gatsby - generator statycznych stron z GraphQL
Dla nauki React i budowania aplikacji SPA (Single Page Application), Vite jest najlepszym wyborem - szybki, prosty i wymieniany w dokumentacji React.
Ra podsumowuje: "Vite to silnik nowej generacji Twojego kosmicznego statku React. Szybki start, natychmiastowe reakcje na zmiany kursu i pełna kontrola nad konfiguracją - wszystko, czego potrzebujesz, aby podbić galaktykę!"
Kod do tej lekcji: App.jsx
1import React, { useState } from 'react';
2
3// Demonstracja struktury projektu Vite + React
4function ViteProjectDemo() {
5 const [activeFile, setActiveFile] = useState('App.jsx');
6
7 const fileStructure = [
8 { name: 'node_modules/', type: 'folder', description: 'Zainstalowane pakiety' },
9 { name: 'public/', type: 'folder', description: 'Pliki statyczne' },
10 { name: ' vite.svg', type: 'file', description: 'Logo Vite' },
11 { name: 'src/', type: 'folder', description: 'Kod źródłowy' },
12 { name: ' assets/', type: 'folder', description: 'Zasoby (obrazy, fonty)' },
13 { name: ' App.jsx', type: 'file', description: 'Główny komponent', active: true },
14 { name: ' App.css', type: 'file', description: 'Style komponentu' },
15 { name: ' main.jsx', type: 'file', description: 'Punkt wejściowy' },
16 { name: ' index.css', type: 'file', description: 'Style globalne' },
17 { name: 'index.html', type: 'file', description: 'Główny HTML (w katalogu głównym!)' },
18 { name: 'vite.config.js', type: 'file', description: 'Konfiguracja Vite' },
19 { name: 'package.json', type: 'file', description: 'Konfiguracja projektu' },
20 ];
21
22 const fileContents = {
23 'App.jsx': `import { useState } from 'react'
24import './App.css'
25
26function App() {
27 const [count, setCount] = useState(0)
28
29 return (
30 <>
31 <h1>Vite + React</h1>
32 <div className="card">
33 <button onClick={() => setCount(c => c + 1)}>
34 count is {count}
35 </button>
36 </div>
37 </>
38 )
39}
40
41export default App`,
42 'main.jsx': `import React from 'react'
43import ReactDOM from 'react-dom/client'
44import App from './App.jsx'
45import './index.css'
46
47ReactDOM.createRoot(
48 document.getElementById('root')
49).render(
50 <React.StrictMode>
51 <App />
52 </React.StrictMode>,
53)`,
54 'vite.config.js': `import { defineConfig } from 'vite'
55import react from '@vitejs/plugin-react'
56
57export default defineConfig({
58 plugins: [react()],
59})`,
60 'package.json': `{
61 "name": "moja-aplikacja",
62 "version": "0.0.0",
63 "type": "module",
64 "scripts": {
65 "dev": "vite",
66 "build": "vite build",
67 "preview": "vite preview"
68 },
69 "dependencies": {
70 "react": "^18.2.0",
71 "react-dom": "^18.2.0"
72 },
73 "devDependencies": {
74 "@vitejs/plugin-react": "^4.2.0",
75 "vite": "^5.0.0"
76 }
77}`
78 };
79
80 return (
81 <div style={{
82 fontFamily: 'Arial, sans-serif',
83 maxWidth: '1000px',
84 margin: '0 auto',
85 padding: '20px'
86 }}>
87 <header style={{
88 background: 'linear-gradient(135deg, #61dafb 0%, #21a1f1 100%)',
89 padding: '30px',
90 borderRadius: '12px',
91 color: 'white',
92 textAlign: 'center',
93 marginBottom: '30px'
94 }}>
95 <h1 style={{ margin: 0, fontSize: '2rem' }}>Vite + React</h1>
96 <p style={{ margin: '10px 0 0 0', opacity: 0.9 }}>
97 Struktura projektu i podstawowe pliki
98 </p>
99 </header>
100
101 <div style={{
102 backgroundColor: '#1e1e1e',
103 borderRadius: '8px',
104 padding: '20px',
105 marginBottom: '30px',
106 fontFamily: 'monospace'
107 }}>
108 <div style={{ color: '#888', marginBottom: '10px' }}>Terminal:</div>
109 <div style={{ color: '#00ff00' }}>$ npm create vite@latest moja-aplikacja -- --template react</div>
110 <div style={{ color: '#888', marginTop: '5px' }}>Scaffolding project in /moja-aplikacja...</div>
111 <div style={{ color: '#00ff00', marginTop: '5px' }}>Done. Now run: cd moja-aplikacja && npm install && npm run dev</div>
112 </div>
113
114 <div style={{ display: 'grid', gridTemplateColumns: '300px 1fr', gap: '20px' }}>
115 <div style={{
116 backgroundColor: '#252526',
117 borderRadius: '8px',
118 padding: '15px'
119 }}>
120 <h3 style={{ color: '#cccccc', margin: '0 0 15px 0', fontSize: '14px' }}>
121 EXPLORER
122 </h3>
123 {fileStructure.map((item, index) => (
124 <div
125 key={index}
126 onClick={() => item.type === 'file' && setActiveFile(item.name.trim())}
127 style={{
128 padding: '8px 10px',
129 color: item.type === 'folder' ? '#dcb67a' : '#9cdcfe',
130 cursor: item.type === 'file' ? 'pointer' : 'default',
131 backgroundColor: activeFile === item.name.trim() ? '#094771' : 'transparent',
132 borderRadius: '4px',
133 fontSize: '14px',
134 fontFamily: 'monospace'
135 }}
136 >
137 {item.type === 'folder' ? '▸' : '•'} {item.name}
138 </div>
139 ))}
140 </div>
141
142 <div style={{
143 backgroundColor: '#1e1e1e',
144 borderRadius: '8px',
145 padding: '20px'
146 }}>
147 <div style={{
148 color: '#888',
149 fontSize: '12px',
150 marginBottom: '10px',
151 borderBottom: '1px solid #333',
152 paddingBottom: '10px'
153 }}>
154 {activeFile}
155 </div>
156 <pre style={{
157 color: '#d4d4d4',
158 margin: 0,
159 fontSize: '14px',
160 lineHeight: '1.5',
161 overflow: 'auto'
162 }}>
163 {fileContents[activeFile] || '// Wybierz plik z listy'}
164 </pre>
165 </div>
166 </div>
167
168 <div style={{
169 marginTop: '30px',
170 padding: '20px',
171 backgroundColor: '#fff3e0',
172 borderRadius: '8px'
173 }}>
174 <h3 style={{ color: '#e65100', marginTop: 0 }}>Komendy startowe</h3>
175 <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: '15px' }}>
176 <div style={{ backgroundColor: 'white', padding: '15px', borderRadius: '8px' }}>
177 <code style={{ color: '#e65100' }}>npm run dev</code>
178 <p style={{ margin: '5px 0 0 0', fontSize: '14px', color: '#666' }}>
179 Uruchamia serwer deweloperski
180 </p>
181 </div>
182 <div style={{ backgroundColor: 'white', padding: '15px', borderRadius: '8px' }}>
183 <code style={{ color: '#e65100' }}>npm run build</code>
184 <p style={{ margin: '5px 0 0 0', fontSize: '14px', color: '#666' }}>
185 Buduje wersję produkcyjną
186 </p>
187 </div>
188 </div>
189 </div>
190 </div>
191 );
192}
193
194export default function App() {
195 return <ViteProjectDemo />;
196}Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Do czego służy Vite w ekosystemie React?
2. Co to jest hot reloading w React?
Zadania praktyczne w grze
- Klikanie w kolejności
Ułóż kroki tworzenia pierwszej aplikacji React:
- Układanie w pionie
Ułóż etapy transpilacji kodu przez Babel od góry do dołu:
- Edytor kodu
Stwórz prosty komponent React App, który wyświetla nagłówek i paragraf powitalny.
- Klikanie w kolejności
Zbuduj polecenie tworzące nowy projekt React z Vite: