Mundarija (47)
- Bu darsda
- 1. Nega bu kerak?
- 2. Loyiha yaratish
- 2.1 npm create vite
- 2.2 Paketlarni o'rnatish
- 3. Fayllar xaritasi
- 3.1 Tuzilma
- 3.2 package.json
- 4. Ilova qanday yuklanadi
- 4.1 Zanjir
- 4.2 index.html
- 4.3 src/main.tsx — React kirish nuqtasi
- 4.4 src/App.tsx — birinchi komponent
- 5. StrictMode — dev rejimdagi qo'shimcha tekshiruv
- 5.1 Nima qiladi
- 5.2 O'lchab ko'ramiz
- 6. Sozlama fayllari
- 6.1 vite.config.ts
- 6.2 tsconfig.app.json
- 6.3 Linter: Oxlint yoki ESLint
- 7. Dev server va build
- 7.1 npm run dev
- 7.2 Fast Refresh: holat saqlanadi
- 7.3 npm run build: bo'sh React qancha turadi
- 8. Vazifalar qadami: React oroli
- 8.1 Reja
- 8.2 Paketlar
- 8.3 Birinchi komponent: src/Izoh.tsx
- 8.4 Kirish nuqtasi: src/main.tsx
- 8.5 TypeScript: jsx bayrog'i
- 8.6 Vite va ESLint
- 8.7 Build va tekshiruvlar
- 8.8 CSP va Fast Refresh
- 9. Ko'p uchraydigan xatolar
- 9.1 Target container is not a DOM element.
- 9.2 Cannot use JSX unless the '--jsx' flag is provided.
- 9.3 Could not read package.json
- 9.4 index.html ni ikki marta bosib ochish
- 9.5 StrictMode ni "tuzatish" uchun o'chirish
- 10. Mashqlar
- 1-mashq (oson): shablonni o'qing
- 2-mashq (o'rta): «Bahor» menyusi
- 3-mashq (qiyin): ikkinchi orol
- 4-mashq: Vazifalar qadami
- 11. Real ishda
- Xulosa
- Manbalar
Birinchi React loyiha: Vite shabloni ichida nima bor — index.html → main.tsx → App
Qisqacha: React loyiha bitta buyruq bilan yaratiladi:
npm create vite@9.2.1 bahor-menyu -- --template react-ts. Ilova shunday yuklanadi: brauzerindex.htmlni ochadi, usrc/main.tsxni chaqiradi,main.tsxesacreateRoot(#root)bilanAppkomponentini<div id="root">ichiga chizadi.StrictModefaqat dev rejimda komponentni ikki marta chaqirib, yashirin xatolarni ko'rsatadi. Bugunvazifalarga ham birinchi React bo'lagi — "orol" qo'shiladi.
Bu darsda
create-vitebilan React + TypeScript loyiha yaratasiz va uni ishga tushirasiz.- Shablondagi har faylni o'qiysiz va qaysi biri 16-qismdan tanish ekanini bilasiz.
index.html→main.tsx→Appzanjirini,createRootva#rootni tushuntira olasiz.StrictModenima qilishini o'lchangan misolda ko'rasiz.vazifalarga React'ni o'rnatib, birinchi komponentni —Izohorolini qo'shasiz.
Oldin bilishingiz kerak: React nima va nega, Vite I: loyiha yaratish, tsconfig: app va node, ESLint II: React plaginlari.
1. Nega bu kerak?
Oldingi darsda React kodini sayt oynasida ishga tushirdik. Bu qulay, lekin haqiqiy ilova bunday yashamaydi. Haqiqiy ilova — papka: fayllar, paketlar, build, lint. Sardorning birinchi savoli ham shu bo'ldi: "React loyihani qayerdan boshlayman?"
Javob: tayyor shablondan. Buni Vite I darsida vanilla-ts uchun qilgansiz. React shabloni deyarli bir xil — faqat uch-to'rtta yangi fayl qo'shiladi. Bu dars — shu fayllar bo'ylab sayohat.
Sayohatdan keyin bilganingizni vazifalar da ishlatamiz. Uni butunlay qayta yozmaymiz. Ilovaning bitta kichik joyini React'ga beramiz, qolgani vanilla bo'lib qoladi. Bu usul orol (island) deyiladi. Ko'p kompaniyalar eski saytni React'ga aynan shunday, oroldan boshlab ko'chiradi.
Hayotiy o'xshatish: yangi oshxona jihozlari. Butun oshxonani buzib qayta qurish shart emas. Avval bitta plitani almashtirasiz, u ishlasa — keyingisini. Oshxona bir kun ham yopilmaydi.
Maslahat: Chiqishlar 2026-10-13 da olingan: Node 24.21.0, npm 11.19.0, create-vite 9.2.1, Vite 8.3.4, React 19.3.0, Chrome 154.
vazifalarqadamidagi chiqishlar — Vite 8.3.3 da. Vaqt (ms), port, hash va papka yo'llari sizda boshqacha bo'ladi.
2. Loyiha yaratish
2.1 npm create vite
npx va npm create darsidan bilasiz: npm create vite create-vite paketini yuklab ishga tushiradi. Savollarni kutmaslik uchun hammasini bir qatorda beramiz:
npm create vite@9.2.1 bahor-menyu -- \
--template react-ts --no-interactive> npx
> create-vite bahor-menyu --template react-ts --no-interactive
│
◇ Scaffolding project in …\bahor-menyu...
│
└ Done. Now run:
cd bahor-menyu
npm install
npm run devreact-ts — React + TypeScript. Faqat JavaScript kerak bo'lsa — react. Yana react-compiler-ts shabloni bor: unda React Compiler yoqilgan, uni 18-qismda ko'ramiz. @9.2.1 — aniq versiya: kursdagi natija sizda ham bir xil chiqishi uchun. O'z loyihangizda @latest yozsangiz bo'ladi.
2.2 Paketlarni o'rnatish
Shablon faqat fayllarni yozadi. Paketlarni o'zimiz o'rnatamiz:
cd bahor-menyu
npm installadded 27 packages, and audited 28 packages in 12s
9 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilitiesNimalar o'rnatildi:
npm lsbahor-menyu@0.0.0 …\bahor-menyu
+-- @types/node@24.19.2
+-- @types/react-dom@19.3.0
+-- @types/react@19.3.0
+-- @vitejs/plugin-react@6.1.2
+-- oxlint@1.87.0
+-- react-dom@19.3.0
+-- react@19.3.0
+-- typescript@6.0.3
`-- vite@8.3.4Bir qiziq narsa. Shablonning package.json ida "react": "^19.2.8" yozilgan, o'rnatilgani esa 19.3.0. Nega? Semver darsini eslang: ^ — "shu major ichida eng yangisi". 19.3.0 2026-09-09 da chiqqan, shablon esa undan oldin yozilgan. Hammasi bo'lib 27 paket, node_modules — 86 MB.
3. Fayllar xaritasi
3.1 Tuzilma
bahor-menyu/
├── .gitignore
├── .oxlintrc.json
├── README.md
├── index.html
├── package.json
├── tsconfig.json
├── tsconfig.app.json
├── tsconfig.node.json
├── vite.config.ts
├── public/
│ ├── favicon.svg
│ └── icons.svg
└── src/
├── main.tsx
├── App.tsx
├── App.css
├── index.css
└── assets/ hero.png, react.svg, vite.svgYarmidan ko'pi sizga tanish. Qaysi fayl qayerdan:
| Fayl | Nima | Qayerda o'qigansiz |
|---|---|---|
index.html |
Kirish nuqtasi (entry) | Vite I |
package.json |
Paketlar va skriptlar | package.json I |
tsconfig.*.json (3 ta) |
TS sozlamasi: app va node | tsconfig: app va node |
vite.config.ts |
Vite sozlamasi | Vite II |
.oxlintrc.json |
Linter sozlamasi | Biome va Oxlint |
public/ |
O'zgarmay ko'chiriladigan fayllar | Vite IV |
src/assets/ |
Import qilinadigan rasmlar | Vite IV |
src/main.tsx, src/App.tsx |
Yangi: React kodi | shu dars |
.tsx — ichida JSX bor TypeScript fayl. JSX yo'q faylda .ts yetadi. Brauzer ikkalasini ham tushunmaydi — Vite ularni JavaScript'ga o'giradi.
3.2 package.json
{
"name": "bahor-menyu",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "oxlint",
"preview": "vite preview"
},
"dependencies": {
"react": "^19.2.8",
"react-dom": "^19.2.8"
},
"devDependencies": {
"@types/node": "^24.13.3",
"@types/react": "^19.2.18",
"@types/react-dom": "^19.2.7",
"@vitejs/plugin-react": "^6.1.1",
"oxlint": "^1.81.0",
"typescript": "~6.0.2",
"vite": "^8.3.0"
}
}Ikki paket — dependencies da, chunki ular brauzerga boradi (package.json II):
react— komponentlar,useStatekabi hooklar, JSX qoidalari. U DOM'ni bilmaydi.react-dom— React daraxtini brauzer DOM'iga chizadigan qism.createRootshundan.
Nega ikkiga bo'lingan? React faqat brauzer uchun emas. Xuddi o'sha react paketi bilan React Native telefon ekraniga, react-dom/server esa serverda HTML satrga chizadi. react — "nima chizish", react-dom — "qayerga chizish".
build skripti tanish: avval tsc -b turlarni tekshiradi, keyin vite build yig'adi. @types/react — React'ning turlari: useState nima qaytarishini TypeScript shulardan biladi.
Tekshirib ko'ring: Kimdir
react-domnidevDependenciesga ko'chirdi. Build ishlaydimi?
Javob
Ishlaydi. Vite ikkala bo'limdagi paketlarni ham yig'ib dist/ ga yozadi — brauzer uchun farqi yo'q. Lekin bu noto'g'ri belgi: o'qigan dasturchi "bu faqat build asbobi" deb o'ylaydi. Server ilovasida esa (npm ci --omit=dev) react-dom umuman o'rnatilmay qolardi. Qoida o'zgarmaydi: ilova ishlaganda kerak bo'ladigan narsa — dependencies.
4. Ilova qanday yuklanadi
4.1 Zanjir
Avval butun yo'l, keyin har halqa alohida:
flowchart TD
A["Brauzer: index.html"] --> B["div id=root — bo'sh"]
A --> C["script: /src/main.tsx"]
C --> D["createRoot(#root)"]
D --> E[".render(App)"]
E --> F["App() — JSX qaytaradi"]
F --> G["react-dom: DOM elementlar"]
G --> BDiagrammadagi asosiy narsa: index.html da #root bo'sh keladi. Ichidagi hamma narsani JavaScript keyin chizadi. Bu — Oldingi darsdagi SPA.
4.2 index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0" />
<title>bahor-menyu</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>vanilla-ts shablonidan farqi ikki joyda: <div id="app"> o'rniga <div id="root"> va main.ts o'rniga main.tsx. root — React jamoalaridagi odat, majburiy emas. Muhimi — main.tsx dagi nom bilan bir xil bo'lsin. Darhol lang="en" ni lang="uz" ga almashtiring: ekran o'quvchi (Malika ishlatadigan dastur) matnni o'zbekcha talaffuz qilishi uchun (HTML hujjat tuzilmasi).
4.3 src/main.tsx — React kirish nuqtasi
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'
createRoot(document.getElementById('root')!).render(
<StrictMode>
<App />
</StrictMode>,
)Shablon qo'shtirnoq va nuqtali vergulni boshqa uslubda yozgan — bu Prettier sozlamasiga bog'liq (Prettier), ma'nosi bir xil. Qatorma-qator:
| Qator | Nima qiladi |
|---|---|
import { createRoot } from 'react-dom/client' |
Brauzer uchun React ildizini yasaydigan funksiya |
import './index.css' |
Umumiy CSS — Vite uni sahifaga ulaydi (Vite IV) |
import App from './App.tsx' |
export default komponent (ESM export) |
document.getElementById('root')! |
Bo'sh <div>; ! — "null emas" (non-null) |
createRoot(…) |
Shu element React'ga beriladi — endi uning ichini React boshqaradi |
.render(<StrictMode><App /></StrictMode>) |
Birinchi chizish: App ni dev tekshiruvi ichida |
Ildiz (root) — React boshqaradigan DOM elementi. createRoot dan keyin uning ichiga qo'lda tegmang (oldingi darsdagi uchinchi xato). Ildizdan tashqaridagi narsa esa React'ga tegishli emas — u yerda vanilla kod bemalol ishlayveradi. Orol usuli shunga tayanadi.
O'sha zanjirni sayt oynasida ishga tushiring. Bu blok main.tsx va kichik App ni bitta faylda birlashtiradi:
import { StrictMode, useState } from "react";
import { createRoot } from "react-dom/client";
function App() {
const [soni, setSoni] = useState(0);
return (
<main>
<h1>«Bahor» menyusi</h1>
<p>Buyurtmalar: {soni} ta</p>
<button onClick={() => setSoni(soni + 1)}>
Buyurtma berish
</button>
</main>
);
}
createRoot(document.getElementById("root")!).render(
<StrictMode>
<App />
</StrictMode>,
);Tugma bir marta bosilgach ekranda:
«Bahor» menyusi
Buyurtmalar: 1 ta
Buyurtma berish4.4 src/App.tsx — birinchi komponent
Shablondagi App.tsx 120 qatordan iborat. Uning asosiy qismi (qolgani — havolalar ro'yxati):
import { useState } from 'react'
import heroImg from './assets/hero.png'
import reactLogo from './assets/react.svg'
import viteLogo from './assets/vite.svg'
import './App.css'
function App() {
const [count, setCount] = useState(0)
return (
<>
<section id="center">
<div className="hero">
<img src={heroImg} className="base" … alt="" />
<img src={reactLogo} className="framework" … />
<img src={viteLogo} className="vite" alt="Vite logo" />
</div>
…
<button
type="button"
className="counter"
onClick={() => setCount((count) => count + 1)}
>
Count is {count}
</button>
</section>
…
</>
)
}
export default AppHammasi oldingi darsdagi sanoq misoli, faqat bezakli. Yangi ko'rinadigan narsalar va ular qachon o'tiladi:
| Kodda | Ma'nosi | Batafsil |
|---|---|---|
import heroImg from './assets/hero.png' |
Rasm yo'li — Vite hash'li nom beradi | Vite IV, Rasm va assetlar |
className="hero" |
HTML'dagi class — JSX'da className |
JSX I |
<> … </> |
Fragment — ortiqcha <div> siz bir nechta element |
JSX II |
setCount((count) => count + 1) |
Updater funksiya — oldingi qiymatdan | State II |
export default App |
Faylning asosiy eksporti | ESM export |
Bularni hozir yodlash shart emas. Har biriga alohida dars bor. Bugun muhimi — fayl qayerdan boshlanib, qayerga borishini bilish.
Tekshirib ko'ring:
index.htmldagi<div id="root">ni<div id="ilova">ga o'zgartirdingiz,main.tsxga tegmadingiz. Nima bo'ladi?
Javob
getElementById('root') null qaytaradi, createRoot(null) esa xato tashlaydi va sahifa bo'sh qoladi. ! bu yerda yordam bermaydi: u faqat TypeScript'ni jim qiladi, ishlash vaqtida hech narsa tekshirmaydi (non-null). Xatoning aniq matni — «Ko'p uchraydigan xatolar» bo'limida.
5. StrictMode — dev rejimdagi qo'shimcha tekshiruv
5.1 Nima qiladi
StrictMode (qat'iy rejim) — o'zi hech narsa chizmaydigan o'ram komponent. Dev rejimda u ichidagi komponentlarni ikki marta chaqiradi. Nega? React komponent toza funksiya bo'lishini kutadi: bir xil kirish — bir xil natija, yon ta'sirsiz. Ikki marta chaqirilganda iflos komponent o'zini oshkor qiladi.
O'xshatish: oshpaz taomni tatib ko'radi, keyin yana bir marta tatib ko'radi. Ikki safar ta'mi har xil bo'lsa — retseptda nimadir noto'g'ri.
5.2 O'lchab ko'ramiz
Shablondagi App ga bitta qator qo'shdik: console.log('App chizildi, count =', count). Sahifani Chrome'da ochib, tugmani bir marta bosdik. Konsolni ikki rejimda yozib oldik:
| Rejim | Konsolda |
|---|---|
npm run dev |
App chizildi, count = 0 × 2, keyin count = 1 × 2 — 4 qator |
npm run build + vite preview |
count = 0, keyin count = 1 — 2 qator |
Shu kodni sayt oynasida ham ko'rasiz — u yerda ham React'ning dev versiyasi ishlaydi:
import { StrictMode, useState } from "react";
import { createRoot } from "react-dom/client";
function App() {
const [soni, setSoni] = useState(0);
console.log("App chizildi, soni =", soni);
return (
<button onClick={() => setSoni(soni + 1)}>Osh +</button>
);
}
createRoot(document.getElementById("root")!).render(
<StrictMode>
<App />
</StrictMode>,
);Konsolda (dev rejim, bir bosishdan keyin):
App chizildi, soni = 0
App chizildi, soni = 0
App chizildi, soni = 1
App chizildi, soni = 1Brauzerga React DevTools kengaytmasi o'rnatilgan bo'lsa, takror qatorlar och rangda ko'rinadi — "bu StrictMode'ning takrori" degan belgi. Production build'da takror yo'q: StrictMode u yerda hech narsa qilmaydi va tezlikka ta'sir qilmaydi. Keyinroq o'rganadigan effektlarni (komponent tashqi dunyo bilan ishlaydigan kodni) ham ikki marta ishga tushiradi — buni StrictMode va effektlar darsida o'lchaymiz.
Diqqat: "Ikki marta chiqyapti, xato!" deb
StrictModeni o'chirib qo'ymang. U topgan muammo production'da ham bor — faqat yashirin. Ikki marta chaqirilganda buzilmaydigan komponent yozish to'g'ri yo'l (Pure komponentlar).
6. Sozlama fayllari
6.1 vite.config.ts
import react from '@vitejs/plugin-react'
import { defineConfig } from 'vite'
// https://vite.dev/config/
export default defineConfig({
plugins: [react()],
})vanilla-ts dan farqi — bitta plagin (Vite plaginlari). @vitejs/plugin-react 6.1 ikki ish qiladi:
- JSX'ni o'giradi.
.tsxdagi<App />nijsx(App, {})chaqiruviga aylantiradi. Ichida Oxc ishlaydi — Transpilyatsiya darsidagi Rust'dagi o'giruvchi. Babel endi kerak emas. - Fast Refresh — React uchun HMR. Komponent faylini saqlasangiz, sahifa qayta yuklanmaydi va komponent holati saqlanadi. Buni «Dev server va build» bo'limida o'lchaymiz.
6.2 tsconfig.app.json
Bu faylni tsconfig: app va node darsida qatorma-qator o'qigansiz. Unda React uchun bitta kalit muhim:
{
"compilerOptions": {
// …
"jsx": "react-jsx"
}
}"react-jsx" — JSX'ni "avtomatik runtime" bilan tekshirish: TypeScript react/jsx-runtime ni o'zi ulaydi deb hisoblaydi. Shuning uchun har faylda import React from 'react' yozish shart emas. Eski kodda bu import har .tsx boshida uchraydi — React 17 gacha majburiy edi.
6.3 Linter: Oxlint yoki ESLint
Shablon sukut bo'yicha Oxlint qo'yadi (Biome va Oxlint). .oxlintrc.json da React'ning ikki qoidasi yoqilgan:
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"plugins": ["react", "typescript", "oxc"],
"rules": {
"react/rules-of-hooks": "error",
"react/only-export-components": [
"warn",
{ "allowConstantExport": true }
]
}
}npm run lint toza shablonda jim tugaydi (chiqish yo'q, xato kodi 0) — muvaffaqiyat belgisi.
ESLint kerak bo'lsa (ko'p jamoalar hali unda) — --eslint bayrog'i:
npm create vite@9.2.1 bahor-eslint -- \
--template react-ts --eslint --no-interactiveBu safar .oxlintrc.json o'rnida eslint.config.js paydo bo'ladi:
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import { defineConfig, globalIgnores } from 'eslint/config'
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
js.configs.recommended,
tseslint.configs.recommended,
reactHooks.configs.flat.recommended,
reactRefresh.configs.vite,
],
languageOptions: {
globals: globals.browser,
},
},
])Bu faylni ESLint II darsida o'qigansiz — u yerdagi bilan bir xil. package.json da esa "lint": "eslint .". vazifalar da ESLint ishlatamiz (16-qismdagi typed linting va XSS qoidalari bor), shuning uchun bugun unga react-hooks plaginini qo'shamiz.
7. Dev server va build
7.1 npm run dev
npm run dev> bahor-menyu@0.0.0 dev
> vite
VITE v8.3.4 ready in 275 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to exposeBrauzerda http://localhost:5173/ ni oching — Vite va React logotiplari va "Count is 0" tugmasi. Server qanday ishlashini Vite I da ko'rgansiz. React'da ikki yangilik bor. Birinchisi: dev server index.html ning <head> boshiga Fast Refresh uchun skript qo'shadi (curl -s http://localhost:5173/ bilan ko'rdik):
<!doctype html>
<html lang="en">
<head>
<script type="module">import { injectIntoGlobalHook } from "/@react-refresh";
injectIntoGlobalHook(window);
window.$RefreshReg$ = () => {};
window.$RefreshSig$ = () => (type) => type;</script>
<script type="module" src="/@vite/client"></script>Ikkinchisi: brauzer /src/main.tsx ni so'raganda, JSX allaqachon o'girilgan bo'ladi. Javobdan bo'lak (importlar va oxiri … bilan qisqartirildi; qator uzun — yon tomonga suring):
createRoot(document.getElementById("root")).render(/* @__PURE__ */ _jsxDEV(StrictMode, { children: /* @__PURE__ */ _jsxDEV(App, {}, void 0, false, {
fileName: _jsxFileName,
lineNumber: 8,
columnNumber: 5
}, this) }, void 0, false, {
…<StrictMode><App /></StrictMode> — oddiy funksiya chaqiruvlariga aylandi. ! o'chib ketdi — u faqat TypeScript uchun edi. fileName va lineNumber — dev'dagi xato xabarlari uchun: React xatoni qaysi fayl, qaysi qatordagi komponentda bo'lganini aytadi. Bu o'giruvning to'liq qoidalarini JSX I darsida ko'ramiz.
7.2 Fast Refresh: holat saqlanadi
Tajriba (headless Chrome 154): "Count is" tugmasini 3 marta bosdik, keyin App.tsx dagi Get started matnini Xush kelibsiz ga o'zgartirib, faylni saqladik. 2 soniyadan keyin sahifada:
| Sarlavha | Tugma | Sahifa qayta yuklandimi | |
|---|---|---|---|
| Saqlashdan oldin | Get started | Count is 3 | — |
| Saqlashdan keyin | Xush kelibsiz | Count is 3 | yo'q |
Terminalda — [vite] (client) hmr update /src/App.tsx. Matn yangilandi, count esa 3 da qoldi. Vite I darsida oddiy .ts modul o'zgarganda sahifa to'liq qayta yuklangan edi — holat yo'qolgan edi. Fast Refresh komponentni almashtiradi, lekin uning holatini saqlaydi. Formani to'ldirib turib uslubni tuzatayotganingizda bu katta qulaylik.
Maslahat: Fast Refresh faqat fayl faqat komponentlar eksport qilganda ishlaydi. Faylda komponent bilan birga oddiy funksiya yoki o'zgarmas ham eksport qilinsa — sahifa to'liq qayta yuklanadi.
only-export-componentsqoidasi aynan shuni ogohlantiradi.
7.3 npm run build: bo'sh React qancha turadi
npm run build> bahor-menyu@0.0.0 build
> tsc -b && vite build
vite v8.3.4 building client environment for production...
transforming...
✓ 20 modules transformed.
rendering chunks...
computing gzip size...
dist/index.html 0.46 kB │ gzip: 0.29 kB
dist/assets/react-CHdo91hT.svg 4.12 kB │ gzip: 2.06 kB
dist/assets/vite-BF8QNONU.svg 8.70 kB │ gzip: 1.60 kB
dist/assets/hero-CLDdwZDr.png 13.05 kB
dist/assets/index-D64VDMd1.css 4.10 kB │ gzip: 1.47 kB
dist/assets/index-CVtPK4EU.js 222.44 kB │ gzip: 69.28 kB
✓ built in 159msBitta sanoq tugmasi — 222 KB JavaScript (gzip 69 KB). vanilla-ts shablonida xuddi shunday tugma — 4.49 KB (gzip 2.02). Farq — React va react-dom ning o'zi. Oldingi darsda aytilgan "kirish narxi" mana shu.
8. Vazifalar qadami: React oroli
8.1 Reja
vazifalar v6 — vanilla ilova. Bugun uning bitta joyini React'ga beramiz: sahifa pastidagi izoh matni ("v3: ro'yxat shu brauzerda…"). Bu eng xavfsiz joy: holati yo'q, hodisasi yo'q. Maqsad — React'ni loyihaga ulash: paketlar, TypeScript, Vite, ESLint, build va 159 ta brauzer tekshiruvi. Komponent esa hozircha oddiy.
flowchart TD
H["index.html"] --> V["asosiy.ts — vanilla"]
H --> M["main.tsx — React"]
V --> R1["forma, ro'yxat, filtr, qidiruv"]
M --> I["div id=izoh — Izoh komponenti"]Ikki skript yonma-yon: vanilla qism o'z elementlarini, React esa faqat #izoh ni boshqaradi. Ular bir-biriga tegmaydi. Keyingi darslarda React'ning hududi kengayib boradi. Mini-ilova darsida butun interfeys React'da bo'ladi.
Yangi branch: build/react.
8.2 Paketlar
vazifalar ning .npmrc sida save-exact=true bor (.npmrc). Shuning uchun versiyalar ^ siz yoziladi:
npm i react@19.3.0 react-dom@19.3.0added 3 packages, and audited 224 packages in 1s
81 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilitiesUchta: react, react-dom va uning bog'liqligi scheduler (React ishni bo'laklarga bo'lib bajaradigan rejalashtiruvchi). Endi build va tekshiruv uchun:
npm i -D @types/react@19.3.0 @types/react-dom@19.3.0 \
@vitejs/plugin-react@6.1.2 eslint-plugin-react-hooks@7.1.1added 41 packages, and audited 265 packages in 9s
85 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilitiesShablondagidan ikki farq bor. Birinchisi — aniq versiyalar (19.3.0, ^ siz). Ikkinchisi — eslint-plugin-react-hooks qo'shildi: vazifalar da Oxlint emas, ESLint. Plaginning 7.1.1 versiyasi ESLint 10 bilan mos: ERESOLVE yo'q (ESLint II dagi peer tuzog'i bu safar chiqmadi). O'rnatishda skript bajaradigan paket yo'q (npm query ":attr(scripts, [install])" → []) — ta'minot zanjiri tekshiruvi.
8.3 Birinchi komponent: src/Izoh.tsx
export function Izoh() {
return (
<p>
<small>
v3: ro'yxat shu brauzerda va «Bahor» mashq serverida
saqlanadi. Server — o'rganish uchun: u qayta ishga tushsa,
ro'yxat shu brauzerdagi nusxadan tiklanadi.
</small>
</p>
);
}Matn — v6 dagi index.html dan aynan ko'chirilgan. Foydalanuvchi farqni sezmasligi kerak. JSX matndagi qator ko'chishlarini bitta bo'sh joyga aylantiradi — matnni qanday bo'lib yozsangiz ham ekranda bitta paragraf. Faylning boshida uch qatorli izoh bor: "komponent — JSX qaytaradigan funksiya; nomi katta harf bilan (kichik harfli <izoh> ni React oddiy HTML teg deb oladi)". Kursdagi kod bloklarida telefon ekraniga sig'maydigan uzun izoh qatorlarini tushirib qoldiramiz — mazmuni matnda.
8.4 Kirish nuqtasi: src/main.tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { Izoh } from "./Izoh.tsx";
const ildiz = document.getElementById("izoh");
if (ildiz === null) {
throw new TypeError("#izoh topilmadi");
}
createRoot(ildiz).render(
<StrictMode>
<Izoh />
</StrictMode>,
);Fayldagi izohlar: "React faqat o'zi olgan bitta elementni boshqaradi — orol (island)" va "StrictMode — faqat dev'da". Shablondan farqi: ! o'rniga aniq tekshiruv. Element topilmasa — o'zimizning tushunarli xato, React'ning umumiy xabari emas. Bu toraytirish — if dan keyin TypeScript ildiz ni HTMLElement deb biladi.
index.html da eski <p> o'rniga bo'sh "joy" va yangi skript:
+ <script type="module" src="src/main.tsx"></script>
</head>
…
- <p><small>v3: ro'yxat shu brauzerda va «Bahor» mashq
- serverida saqlanadi. Server — o'rganish uchun: u qayta
- ishga tushsa, ro'yxat shu brauzerdagi nusxadan
- tiklanadi.</small></p>
+ <!-- React oroli (17/#02): ichini src/main.tsx chizadi -->
+ <div id="izoh"></div>8.5 TypeScript: jsx bayrog'i
Fayllarni qo'shib, npm run tip ni ishga tushirdik — tsconfig.app.json ga hali tegmagan edik:
> tip
> tsc -b
src/Izoh.tsx(6,5): error TS17004: Cannot use JSX unless the '--jsx' flag is provided.
src/Izoh.tsx(7,7): error TS17004: Cannot use JSX unless the '--jsx' flag is provided.
src/main.tsx(6,22): error TS6142: Module './Izoh.tsx' was resolved to '…/src/Izoh.tsx', but '--jsx' is not set.
src/main.tsx(15,3): error TS17004: Cannot use JSX unless the '--jsx' flag is provided.
src/main.tsx(16,5): error TS17004: Cannot use JSX unless the '--jsx' flag is provided.Tarjima: "--jsx bayrog'i berilmaguncha JSX ishlatib bo'lmaydi." TypeScript .tsx faylni ko'rdi ("include": ["src"]), lekin JSX'ni qanday tushunishni bilmaydi. Tuzatish — shablondagi kalit:
+ "jsx": "react-jsx",Ustidagi izoh: "<Izoh /> → jsx() chaqiruvi, react/jsx-runtime dan avtomatik import". Shundan keyin npm run tip jim tugaydi.
8.6 Vite va ESLint
vite.config.ts ga plagin — shablondagidek:
+import react from "@vitejs/plugin-react";
…
plugins: [
+ react(),
qobiqPlagini(),eslint.config.js da uch o'zgarish. Birinchisi — files naqshlariga tsx qo'shildi ("**/*.{ts,tsx}"), aks holda yangi fayllar tekshirilmasdi. Ikkinchisi — React hooklar plagini (izohi qisqartirilgan):
{
// React qoidalari (17/#02): hooklar qoidasi, effekt
// bog'liqliklari va React Compiler tahlili asosidagi qoidalar
files: ["src/**/*.{ts,tsx}"],
extends: [reactHooks.configs.flat.recommended],
},Uchinchisi — XSS himoyasi (XSS va DOM xavfsizligi). vazifalar da innerHTML allaqachon taqiqlangan. React'da HTML'ni to'g'ridan-to'g'ri yozishning bitta yo'li bor — dangerouslySetInnerHTML atributi. Uni ham taqiqlaymiz:
// no-restricted-syntax ro'yxatiga yangi element
{
// React'dagi innerHTML (17/#02): JSX matnni o'zi ekranlaydi,
// HTML faqat shu atribut orqali kiradi
selector: "JSXAttribute[name.name='dangerouslySetInnerHTML']",
message: "XSS: matnni JSX ichida {matn} qilib yozing.",
},Sinab ko'rdik — vaqtinchalik src/Xavf.tsx da <p dangerouslySetInnerHTML={{ __html: matn }} />:
npx eslint src/Xavf.tsx…\src\Xavf.tsx
2:13 error XSS: matnni JSX ichida {matn} qilib yozing no-restricted-syntax
✖ 1 problem (1 error, 0 warnings)JSX'da {matn} doim matn bo'lib chiqadi: <b> yozilgan satr ekranda <b> harflari bo'lib ko'rinadi, qalin shrift bo'lmaydi. Bu — React'ning sukut bo'yicha XSS himoyasi (JSX II da sinaymiz).
Yana ikki kichik o'zgarish. package.json da "lint": "eslint . --max-warnings=0": ogohlantirish ham xato hisoblanadi. Hooklar qoidalarining bir qismi "warn" darajasida — ular jim o'tib ketmasin. .lintstagedrc.json da "*.{js,ts,tsx}" — commit oldidan .tsx ham tekshiriladi (Husky va lint-staged).
8.7 Build va tekshiruvlar
npm run buildvite v8.3.3 building client environment for production...
transforming...
<script src="assets/js/tema.js"> in "/index.html" can't be bundled without type="module" attribute
✓ 35 modules transformed.
rendering chunks...
computing gzip size...
dist/index.html 5.16 kB │ gzip: 1.84 kB
dist/assets/index-BI1hyTgJ.css 3.59 kB │ gzip: 1.29 kB
dist/assets/js/tema.js 0.16 kB │ gzip: 0.15 kB │ map: 0.94 kB
dist/assets/olchov-G4bloHwN.js 8.92 kB │ gzip: 3.42 kB │ map: 22.87 kB
dist/assets/index-BD8i4HYm.js 244.82 kB │ gzip: 77.81 kB │ map: 1,160.66 kB
✓ built in 804ms
sw.js: QOBIQ — 12 ta, VERSIYA — v6-88dfa28atema.js haqidagi ogohlantirish 16-qismdan tanish — u ataylab oddiy skript. Vite ikki modul skriptini (asosiy.ts va main.tsx) bitta index-….js ga yig'di.
Brauzer yuklaydigan JS + CSS (16-qismdagi o'lchov skripti bilan):
| Xom | gzip | |
|---|---|---|
| v6 (vanilla) | 38 066 B | 14 279 B |
| Bugun (React oroli) | 257 503 B | 81 691 B |
Bitta <p> uchun +67 KB gzip. Qimmat — lekin bu bir martalik narx: keyingi komponentlar deyarli hech narsa qo'shmaydi. Qism oxirida, butun ilova React'da bo'lganda, jami 83.2 KB bo'ladi.
Qolgan tekshiruvlar: npm test — 146/146, npm run lint, npm run format:check, npm run tip — toza. 159 ta brauzer tekshiruvi (dist/ da, CSP va Trusted Types bilan) — 159/159. Foydalanuvchi uchun hech narsa o'zgarmadi.
8.8 CSP va Fast Refresh
vazifalar da CSP bor: script-src 'self' — HTML ichidagi skript taqiqlangan (CSP). Dev server qo'shadigan Fast Refresh skripti esa aynan HTML ichida (inline). Dev'da buzilish bo'lmaydimi?
Tekshirdik: CSP buzilishi 0, Fast Refresh ishlaydi (Izoh.tsx dagi matnni o'zgartirganda sahifa qayta yuklanmadi). Sababi — skript qayerga qo'yilganida. Vite uni <head> ning eng boshiga, CSP <meta> dan oldin yozadi. <meta> dagi CSP esa faqat o'zidan keyingi elementlarga ta'sir qiladi. Production build'da bu skript umuman yo'q.
Commit:
build: React 19.3 va plugin-react — birinchi komponent (Izoh oroli)Diff: 9 fayl (lock bilan), PR — 16-qismdagidek, gh pr merge --merge.
9. Ko'p uchraydigan xatolar
9.1 Target container is not a DOM element.
index.html da id="root", main.tsx da esa boshqa nom:
import { createRoot } from "react-dom/client";
function App() {
return <p>«Bahor» menyusi</p>;
}
// index.html da <div id="root">, biz esa "app" deb yozdik
createRoot(document.getElementById("app")!).render(<App />);Konsolda:
Uncaught Error: Target container is not a DOM element.Tarjima: "Nishon konteyner DOM elementi emas." getElementById("app") null qaytardi, createRoot esa haqiqiy element kutadi. TypeScript jim — ! uni ishontirdi. Tuzatish: nomlarni bir xil qiling yoki vazifalar dagidek if (ildiz === null) tekshiruvini yozing.
9.2 Cannot use JSX unless the '--jsx' flag is provided.
Mavjud TypeScript loyihasiga React qo'shganda tsconfig.app.json ga "jsx": "react-jsx" yozilmagan. «Vazifalar qadami» dagi to'liq misolni ko'ring.
9.3 Could not read package.json
npm run dev ni loyiha papkasidan tashqarida ishga tushirish:
npm error code ENOENT
npm error syscall open
npm error path …\package.json
npm error errno -4058
npm error enoent Could not read package.json: Error: ENOENT: no such file or directory, open '…\package.json'npm package.json ni joriy papkadan qidiradi. npm create dan keyin cd bahor-menyu ni unutmang.
9.4 index.html ni ikki marta bosib ochish
Sahifa bo'sh, konsolda modul xatosi. Brauzer .tsx ni bajara olmaydi va file:// dan modul yuklamaydi (Asboblar zanjiri). Dev'da — npm run dev, build natijasini ko'rish uchun — npm run preview.
9.5 StrictMode ni "tuzatish" uchun o'chirish
Konsolda har narsa ikki marta chiqadi — bu xato emas. «StrictMode — dev rejimdagi qo'shimcha tekshiruv» bo'limidagi o'lchovni eslang.
10. Mashqlar
Mashq papkasi: kurs/mashqlar/17/02-birinchi-loyiha/. Loyihani «Loyiha yaratish» bo'limidagidek yarating.
1-mashq (oson): shablonni o'qing
Loyihani yaratib, npm run dev ni ishga tushiring va javob bering:
- React chizadigan element
index.htmlda qanday id bilan: createRootqaysi paketdan import qilinadi:StrictModetakrori qaysi buyruqda ko'rinmaydi —npm run devyokinpm run preview:
Yechim
root — <div id="root">. createRoot — react-dom/client dan: DOM bilan ishlash react-dom ning vazifasi, react esa DOM'ni bilmaydi. npm run preview — u production build'ni ko'rsatadi, StrictMode esa faqat dev'da ikki marta chaqiradi.
2-mashq (o'rta): «Bahor» menyusi
Shablondagi App.tsx ni tozalang (rasm va CSS importlari kerak emas) va «Bahor» menyusini chizing. Karta uchun alohida fayl — src/MenuCard.tsx. Unda MenuCard komponenti bo'lsin, props: name: string va price: number. Bu — oldingi darsdagi MenuCard ning TypeScript varianti. App to'rtta karta chizsin: osh 35000, lag'mon 28000, manti 30000, ko'k choy 5000. Props turi — oddiy type (type va interface). Natijani npm run dev da tekshiring, keyin npm run build va npm run lint toza bo'lsin.
Yechim
src/MenuCard.tsx:
// MenuCard.tsx — bitta taom kartasi (17/02, 2-mashq)
type MenuCardProps = { name: string; price: number };
export function MenuCard({ name, price }: MenuCardProps) {
return (
<li>
{name} — {price} so'm
</li>
);
}src/App.tsx:
// App.tsx — «Bahor» menyusi (17/02, 2-mashq)
import { MenuCard } from "./MenuCard.tsx";
export default function App() {
return (
<main>
<h1>«Bahor» menyusi</h1>
<ul>
<MenuCard name="Osh" price={35000} />
<MenuCard name="Lag'mon" price={28000} />
<MenuCard name="Manti" price={30000} />
<MenuCard name="Ko'k choy" price={5000} />
</ul>
</main>
);
}Ikki fayl bitta blokda — sayt oynasida sinash uchun:
type MenuCardProps = { name: string; price: number };
function MenuCard({ name, price }: MenuCardProps) {
return (
<li>
{name} — {price} so'm
</li>
);
}
export default function App() {
return (
<main>
<h1>«Bahor» menyusi</h1>
<ul>
<MenuCard name="Osh" price={35000} />
<MenuCard name="Lag'mon" price={28000} />
<MenuCard name="Manti" price={30000} />
<MenuCard name="Ko'k choy" price={5000} />
</ul>
</main>
);
}Ekranda:
«Bahor» menyusi
Osh — 35000 so'm
Lag'mon — 28000 so'm
Manti — 30000 so'm
Ko'k choy — 5000 so'msrc/assets/ va App.css ni o'chirsangiz ham build buzilmaydi — ular faqat App.tsx dan import qilingan edi. npm run build — JS 220.17 KB (gzip 68.86): rasm va ko'p CSS ketdi, React narxi qoldi.
3-mashq (qiyin): ikkinchi orol
Sahifada ikkita mustaqil React ildizi bo'lsin. index.html da #root dan keyin <footer id="ish-vaqti"></footer>. src/IshVaqti.tsx — "Ish vaqti: 07:00–23:00. Hozir: ochiq" matni va "Almashtir" tugmasi (bosilganda "ochiq" ↔ "yopiq"; useState(true) va ternary operator). main.tsx da ikkinchi createRoot. Tekshiring: "Almashtir" bosilganda menyu o'zgarmaydi.
Yechim
src/IshVaqti.tsx:
// IshVaqti.tsx — ikkinchi React "orol" (17/02, 3-mashq)
import { useState } from "react";
export function IshVaqti() {
const [ochiq, setOchiq] = useState(true);
return (
<p>
Ish vaqti: 07:00–23:00. Hozir: {ochiq ? "ochiq" : "yopiq"}
{" "}
<button onClick={() => setOchiq(!ochiq)}>Almashtir</button>
</p>
);
}src/main.tsx:
// main.tsx — ikki ildiz: #root va #ish-vaqti (17/02, 3-mashq)
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "./index.css";
import App from "./App.tsx";
import { IshVaqti } from "./IshVaqti.tsx";
createRoot(document.getElementById("root")!).render(
<StrictMode>
<App />
</StrictMode>,
);
createRoot(document.getElementById("ish-vaqti")!).render(
<StrictMode>
<IshVaqti />
</StrictMode>,
);{" "} — matn va tugma orasidagi bo'sh joy: JSX qator oxiridagi bo'shliqni tashlab yuboradi (JSX II da). Biz vite preview da headless Chrome bilan tekshirdik: "Almashtir" bosilgach #ish-vaqti "yopiq" bo'ldi, #root matni o'zgarmadi, konsolda xato yo'q. Ikki ildiz — ikki alohida React daraxti: biri ikkinchisining holatini ko'rmaydi. Bitta sahifada bir nechta orol — eski saytni ko'chirishning odatiy usuli. vazifalar da hozir bitta orol bor, Ro'yxatlar va key darsida ikkinchisi (ro'yxat) qo'shiladi.
4-mashq: Vazifalar qadami
vazifalar da build/react branch'ini oching va «Vazifalar qadami: React oroli» bo'limidagi o'zgarishlarni kiriting: paketlar, Izoh.tsx, main.tsx, index.html, tsconfig.app.json (jsx), vite.config.ts, eslint.config.js, package.json (--max-warnings=0), .lintstagedrc.json. Keyin npm run check va npm run build toza bo'lsin, npm run dev da izoh matni avvalgidek ko'rinsin.
Yechim
Tekshiruv ro'yxati:
npm run tip—TS17004bo'lsa,jsxkaliti unutilgan.npm run lint—.tsxfayllar ham tekshiriladimi?filesnaqshlaridatsxbormi?npm run build—index-….jstaxminan 245 KB (gzip ~78). Bundan ancha kichik bo'lsa —main.tsxindex.htmlga ulanmagan.npm test— 146/146 (sof mantiq testlari React'dan bexabar).- Brauzerda: izoh matni pastda, DevTools Elements'da
<div id="izoh"><p><small>…— React chizgan.
Yakuniy kod — build: React 19.3 va plugin-react — birinchi komponent (Izoh oroli) commit'i. PR'ni birlashtiring.
11. Real ishda
- Yangi loyiha: ishda React loyihani noldan kamdan-kam yaratasiz — ko'pincha tayyor repo beriladi. Lekin uning ichida aynan shu fayllar:
main.tsx,App.tsx,vite.config.ts, uchtatsconfig. Bugungi xarita begona loyihada ham ishlaydi (Begona repoda orientatsiya). - Orol usuli: eski saytni (PHP, jQuery, Django shablonlari) React'ga ko'chirish ko'pincha bitta
createRootdan boshlanadi. Butun sayt qayta yozilmaydi. - Intervyuda: "
reactvareact-domfarqi?", "StrictMode nima qiladi va nega konsolda ikki marta chiqadi?", "Create React App o'rniga nima ishlatiladi?" (javob: Vite yoki framework). - Kod ko'rib chiqishda:
dangerouslySetInnerHTMLva o'chirib qo'yilganStrictMode— tajribali dasturchi birinchi qaraydigan joylar.
Xulosa
npm create vite@9.2.1 <nom> -- --template react-ts— React + TypeScript loyiha; keyinnpm installvanpm run dev.- Zanjir:
index.html(<div id="root">) →src/main.tsx(createRoot(...).render(...)) →Appkomponenti. react— komponentlar va hooklar,react-dom— ularni brauzer DOM'iga chizish.StrictModedev'da komponentni ikki marta chaqiradi (o'lchandi: 4 qator va 2 qator), production'da hech narsa qilmaydi.@vitejs/plugin-react— JSX o'girish (Oxc) va Fast Refresh (holat saqlanadi);tsconfigda"jsx": "react-jsx".vazifalarda React —#izohoroli: bundle 14.3 → 81.7 KB gzip, testlar 146/146, brauzer 159/159.
Keyingi dars: JSX I: JSX aslida JavaScript — <App /> qanday qilib jsx() chaqiruviga aylanishini ko'ramiz va JSX'ning hamma qoidalari shundan kelib chiqishini tushunamiz.
Manbalar
- React hujjatlari: "Build a React app from Scratch", "createRoot", "StrictMode" — react.dev
- Vite: "Getting Started" (
npm create vite, shablonlar) — vite.dev/guide; create-vite — github.com/vitejs/vite/tree/main/packages/create-vite @vitejs/plugin-react— github.com/vitejs/vite-plugin-reacteslint-plugin-react-hooks— react.dev/reference/eslint-plugin-react-hooks
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!