Mundarija (31)
- Bu darsda
- 1. Nega bu kerak?
- 2. Brauzer nimani tushunadi
- 2.1 Uch til va boshqa hech narsa
- 2.2 Tajriba: brauzerga .ts va .jsx beramiz
- 3. Asboblar zanjiri
- 3.1 Toolchain nima
- 3.2 Halqalar birma-bir
- 3.3 Hammasi Node'da ishlaydi
- 4. Ikki rejim: dev va build
- 4.1 Dev server: yozayotganda
- 4.2 Build: mijozga chiqarishdan oldin
- 4.3 Uch papka: src/, node_modules/, dist/
- 5. vazifalar: bugun va 16-qism oxirida
- 5.1 Bugungi zanjir — v5
- 5.2 16-qism oxiridagi zanjir — v6
- 5.3 Raqamlar: qayerga boramiz
- 5.4 Minifikatsiya va hash — ko'z bilan
- 5.5 Oxirgi halqa: Pages va CDN
- 6. 16-qism xaritasi
- 7. Ko'p uchraydigan xatolar
- 7.1 dist/index.html ni ikki marta bosib ochish
- 7.2 node_modules/ ni ko'chirish yoki git'ga qo'shish
- 7.3 "Build o'tdi — demak hammasi to'g'ri"
- 8. Mashqlar
- 1-mashq (oson): Halqani toping
- 2-mashq (o'rta): v5 dist/ ni o'rganing
- 3-mashq (qiyin): O'lchov skripti
- 9. Real ishda
- Xulosa
- Manbalar
Frontend asboblar zanjiri: manba koddan brauzergacha
Qisqacha: Brauzer faqat HTML, CSS va JavaScript'ni tushunadi. Biz esa TypeScript, modullar va npm paketlari bilan yozamiz. Kodni brauzerga tayyorlaydigan vositalar ketma-ketligi — asboblar zanjiri (toolchain). npm paketlarni olib keladi,
tsctekshiradi, bundler (masalan Vite) kodni yig'ib, siqib,dist/ga yozadi. GitHub Pages esadist/ni CDN orqali tarqatadi. 16-qismdavazifalarshu zanjirga o'tadi: brauzer yuklaydigan kod 85.8 KB dan 38.1 KB ga, fayllar 20 tadan 4 taga tushadi.
Bu darsda
- Brauzer nega
.tsva.tsxni bajarmasligini haqiqiy xato xabarlari bilan tushuntira olasiz. - Zanjirning har halqasi (paket menejeri, tekshiruvchi, transpiler, bundler, minifikator, deploy) nima qilishini ayta olasiz.
- Dev server va build farqini,
src/,node_modules/,dist/vazifasini bilasiz. vazifalarning bugungi (v5) va 16-qism oxiridagi (v6) zanjirini solishtira olasiz.- 16-qism bloklari
vazifalarga nima berishini bilasiz.
Oldin bilishingiz kerak: npm'ga birinchi qadam, TypeScript build: tsc, bundler'lar va tsgo, GitHub Pages'ga Actions orqali deploy, HTTP sarlavhalari, MIME turlari va kesh.
1. Nega bu kerak?
15-qismning oxirgi darsida vazifalar v5 ni yakunladik: 2 721 qator TypeScript, 143 test, Lighthouse 100. Endi 16-qism boshlanadi. Bu qismda yangi til o'rganmaymiz. Bu qism — asboblar haqida: kodni yozishdan saytga chiqarishgacha uni kim, qanday qayta ishlaydi.
Nega bu alohida qism? Bir voqea. Jasur aka «Bahor» uchun boshqa dasturchilar yozgan yangi menyu loyihasini oldi va Sardorga berdi. Sardor uni GitHub'dan yuklab, papkani ochdi. Ichida package.json da 30 dan ortiq paket, vite.config.ts, tsconfig.app.json, .nvmrc, .husky/ papkasi bor edi. src/ ichida esa .tsx fayllar.
Sardor index.html ni ikki marta bosib ochdi. Sahifa bo'sh. Keyin npm run build buyrug'ini topdi, dist/index.html ni ochdi — yana bo'sh. Konsolda qizil xatolar. Kod ishlaydi — boshqa dasturchilarda ishlagan. Sardor esa loyihaga qanday "kirishni" bilmaydi.
Bu dars — xarita. Har fayl va har buyruq zanjirning qaysi halqasiga tegishli ekanini bilsangiz, notanish loyiha qo'rqinchli bo'lmaydi. Keyingi 47 dars har halqani chuqur ochadi.
Hayotiy o'xshatish: «Bahor» oshxonasi. Mijozning stoliga faqat tayyor osh keladi. Undan oldin esa bozor, ombor, sifat nazorati, oshpaz va ofitsiant bor. Mijoz ularni ko'rmaydi, lekin bittasi buzilsa — osh ham yo'q. Frontend'da mijoz — brauzer, osh — dist/ dagi fayllar.
2. Brauzer nimani tushunadi
2.1 Uch til va boshqa hech narsa
Brauzer HTML, CSS va JavaScript'ni tushunadi. Yana rasm, shrift, WebAssembly kabi tayyor formatlarni ham. TypeScript ular orasida yo'q. JSX (React'ning HTML'ga o'xshash yozuvi — 17-qismda o'rganamiz, hozir bilish shart emas) ham yo'q. .tsx — TypeScript va JSX bir faylda, demak brauzer uchun ikki karra begona.
Keling, tekshirib ko'ramiz. Mana oddiy TypeScript fayli app.ts:
const price: number = 35000;
console.log("narx", price); // narx 35000Node 24 uni bajaradi: TypeScript'ni o'rnatish darsida ko'rganimizdek, u turlarni o'chirib tashlaydi. Endi shu faylni brauzerga beramiz:
<script type="module" src="./app.ts"></script>2.2 Tajriba: brauzerga .ts va .jsx beramiz
Biz bu sahifani Chrome 154 da uch xil holatda ochdik (kichik lokal server orqali). Har holatda konsolda chiqqan haqiqiy xabar:
| Server faylni qanday yubordi | Chrome 154 konsolida |
|---|---|
app.ts, Content-Type: video/mp2t |
Failed to load module script (MIME) |
app.ts, Content-Type: text/javascript |
SyntaxError: Missing initializer in const declaration |
app.jsx, Content-Type: text/javascript |
SyntaxError: Unexpected token '<' |
Birinchi holat — eng ko'p uchraydigani. Birinchi qatordagi to'liq xabar:
Failed to load module script: Expected a JavaScript-or-Wasm module script but the server responded with a MIME type of "video/mp2t". Strict MIME type checking is enforced for module scripts per HTML spec.Tarjimasi: "Modul skriptini yuklab bo'lmadi: JavaScript yoki Wasm moduli kutilgan edi, server esa video/mp2t MIME turini yubordi. Modul skriptlari uchun MIME turi qat'iy tekshiriladi".
Nega video? .ts kengaytmasi TypeScript'dan oldin ham bor edi: u MPEG-TS video formati (televidenie oqimlari). Ko'p serverlar kengaytmaga qarab turni tanlaydi. Masalan, Node'dagi Express ishlatadigan mime-types paketi app.ts uchun video/mp2t qaytaradi — buni ham tekshirdik. MIME turlari darsidan bilasiz: brauzer faylni nomiga emas, Content-Type sarlavhasiga qarab o'qiydi.
Ikkinchi holatda server "bu JavaScript" dedi va brauzer const price: dagi ikki nuqtaga qoqildi. Xabar "const e'lonida boshlang'ich qiymat yo'q" deydi. Chalg'ituvchi, to'g'rimi? JavaScript const price dan keyin = kutgan edi, : ni esa tushunmadi. Uchinchi holatda < — JavaScript'da "kichik" operatori, = dan keyin esa ma'nosiz:
const title = <h1>Bahor</h1>;
console.log(title);Xulosa: brauzerga yetib boradigan har fayl oddiy JavaScript bo'lishi shart. Turlar, JSX, import "web-vitals" kabi paket nomlari — hammasi avval qayta ishlanishi kerak.
Tekshirib ko'ring: Node 24
node app.tsni bajaradi, Chrome 154 esaapp.tsni bajarmaydi. Nega farq bor?
Javob
Node 24 ga turlarni o'chirish imkoniyati (type stripping) qo'shilgan: u : number ni o'zi olib tashlab, qolganini bajaradi. Brauzerlarda bunday imkoniyat yo'q — ular faqat standart JavaScript'ni bajaradi. Shuning uchun brauzer uchun kodni oldindan, kompyuterimizda aylantirib qo'yamiz.
3. Asboblar zanjiri
3.1 Toolchain nima
Asboblar zanjiri (toolchain) — manba kodni brauzerga yetkaziladigan fayllarga aylantiradigan vositalar ketma-ketligi. Har vosita bitta ishni qiladi va natijani keyingisiga uzatadi. Xuddi oshxonadagi kabi: bozorchi go'shtni olib keladi, oshpaz pishiradi, ofitsiant olib boradi.
Manba kod (source code) — siz yozadigan va o'qiydigan kod: src/*.ts, index.html, CSS. U odam uchun: izohlar, uzun nomlar, ko'p fayllar. Zanjir oxirida esa mashina uchun fayllar chiqadi: kam, kichik, izohsiz.
Diagrammaga qarang: chap tomonda siz yozadigan narsa, o'ng tomonda brauzer oladigan narsa. O'rtadagi har to'rtburchakni 16-qismda alohida o'rganamiz.
flowchart TB
S["src/*.ts<br/>index.html, CSS"] --> N["npm<br/>node_modules/"]
N --> T["tsc, ESLint<br/>tekshiradi"]
T --> V["Vite: Oxc + Rolldown<br/>o'giradi, yig'adi"]
V --> M["minifikatsiya<br/>+ hash"]
M --> D["dist/<br/>4 ta fayl"]
D --> P["GitHub Pages<br/>CDN"]
P --> B["brauzer"]3.2 Halqalar birma-bir
| Halqa | Nima qiladi | Bizdagi vosita |
|---|---|---|
| Paket menejeri | Begona kodni yuklab, node_modules/ ga qo'yadi |
npm 11 |
| Tekshiruvchilar | Xatoni topadi, kodni o'zgartirmaydi | tsc, ESLint, Prettier, node --test |
| Transpiler | TS va yangi JS ni brauzer JS'iga o'giradi | Oxc (Vite ichida) |
| Bundler | Ko'p modulni bir necha faylga yig'adi | Rolldown (Vite ichida) |
| Halqa | Nima qiladi | Bizdagi vosita |
|---|---|---|
| Minifikator | Bo'sh joy, izoh, uzun nomlarni olib tashlaydi | Oxc, Lightning CSS |
| Hash | Fayl nomiga tarkib "barmoq izi"ni qo'shadi | Vite |
| Deploy va CDN | dist/ ni internetga chiqaradi |
GitHub Pages (Actions) |
Jadval telefonga sig'ishi uchun ikkiga bo'lingan. Atamalarni bittalab ochamiz.
Paket menejeri (package manager) — boshqalar yozgan kodni (paketlarni) yuklab oladigan va versiyasini kuzatadigan dastur. Siz npm bilan birinchi qadam darsida tanishgansiz: npm install paketlarni node_modules/ ga qo'yadi. 16-qismda npm'ga 17 ta dars ajratilgan — eng katta blok.
Transpiler — tsc va bundler'lar darsidan tanish: kodni boshqa tilga yoki boshqa versiyaga o'giradigan dastur, turlarni tekshirmaydi. Vite 8 ichida bu ishni Oxc (Rust'da yozilgan vosita) qiladi.
Bundler (yig'uvchi) — ko'p modulni import zanjiri bo'yicha kuzatib, bir yoki bir necha faylga birlashtiradigan vosita. Vite 8 ichida bu Rolldown (u ham Rust'da). Bundler kutubxonadan ishlatilmagan kodni ham tashlab yuboradi — buni Tree shaking darsida ko'ramiz.
Minifikatsiya (minification) — kodning ma'nosini o'zgartirmay, hajmini kichraytirish: bo'sh joylar, izohlar o'chadi, ichki nomlar bir harfga qisqaradi. Oshxona tilida: osh o'sha-o'sha, faqat ixcham qopqoqli idishga solingan.
Hash — fayl tarkibidan hisoblangan qisqa "barmoq izi": index-C4s8yKGl.js. Tarkib bir harf o'zgarsa, iz ham o'zgaradi. Nega kerakligini pastroqda, raqamlar bilan ko'ramiz.
3.3 Hammasi Node'da ishlaydi
Zanjirning bitta qiziq tomoni bor. Natija brauzer uchun, lekin vositalarning hammasi — npm, tsc, ESLint, Vite — sizning kompyuteringizda, Node.js ichida ishlaydi. Shuning uchun Node versiyasi ham zanjirning bir qismi. Bir dasturchida Node 22, boshqasida Node 24 bo'lsa, bir xil loyiha ikki xil natija berishi mumkin. Buni keyingi darsda hal qilamiz.
Tekshirib ko'ring: Transpiler va bundler ikkalasi ham "kodni o'zgartiradi". Farqi nimada?
Javob
Transpiler har faylni alohida o'giradi: .ts dan turlarni olib tashlaydi, yangi sintaksisni eskisiga aylantiradi. Fayllar soni o'zgarmaydi. Bundler esa fayllar orasidagi import larni kuzatadi va ularni birlashtiradi: 15 ta modul bitta faylga aylanishi mumkin. Vite ikkalasini ham qiladi, lekin ichida ikki xil vosita ishlaydi (Oxc va Rolldown).
4. Ikki rejim: dev va build
Zanjir ikki rejimda ishlaydi: kod yozayotganda (natija darhol kerak) va saytni mijozga chiqarishda (natija kichik va tez bo'lishi kerak).
4.1 Dev server: yozayotganda
Dev server (ishlab chiqish serveri) — kod yozayotganda ishlatiladigan lokal server. U fayllarni oldindan yig'maydi: brauzer qaysi faylni so'rasa, o'shani o'sha zahoti o'giradi.
npm run dev ni vazifalar ga 16-qism o'rtasida qo'shamiz. Hozir uni oldindan ko'ramiz (16-qism oxiridagi loyihaning haqiqiy chiqishi):
npm run dev> dev
> vite --port 5397 --strictPort
VITE v8.3.3 ready in 759 ms
➜ Local: http://localhost:5397/
➜ Network: use --host to exposePort raqamini biz alohida tanladik. Sukut bo'yicha Vite 5173 ni oladi. 759 ms — ishga tushish vaqti, sizda boshqa raqam chiqadi.
Endi brauzer src/vazifa.ts ni so'raganda nima bo'lishini kuzatamiz. Manba faylda turlar bor:
export class VazifaXatosi extends Error {
readonly kod: VazifaXatosiKodi;
constructor(
xabar: string,
sozlama?: ErrorOptions & { kod?: VazifaXatosiKodi },
) {
super(xabar, sozlama);Dev server esa xuddi shu manzil (/src/vazifa.ts) bo'yicha Content-Type: text/javascript sarlavhasi bilan quyidagini qaytardi:
export class VazifaXatosi extends Error {
kod;
constructor(xabar, sozlama) {
super(xabar, sozlama);Turlar va readonly yo'q, qolgani o'sha-o'sha. Nom .ts bo'lib qoldi, ichidagisi esa JavaScript — brauzer sarlavhaga qaraydi, shuning uchun ishlaydi.
Dev server'ning yana bir kuchi — HMR (Hot Module Replacement, modulni issiq almashtirish): faylni saqlasangiz, sahifa qayta yuklanmaydi, faqat o'zgargan modul almashadi. Batafsil — Vite I darsida.
4.2 Build: mijozga chiqarishdan oldin
Build (yig'ish) — loyihani bir marta, oxirigacha qayta ishlab, tayyor fayllarni papkaga yozish. Natija odatda dist/ (distribution — "tarqatish uchun") papkasiga tushadi. Shu papka saytga chiqadi.
16-qism oxirida vazifalar ning buildi shunday ko'rinadi (haqiqiy chiqish, ranglar olib tashlangan). Chiqish uzun, lekin hozir faqat dist/ bilan boshlanadigan beshta qatorga qarang: ular — brauzerga boradigan fayllar va ularning hajmi.
npm run build> build
> tsc -b && vite build
vite 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
✓ 23 modules transformed.
rendering chunks...
computing gzip size...
dist/index.html 5.27 kB │ gzip: 1.89 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-C4s8yKGl.js 25.38 kB │ gzip: 9.51 kB │ map: 115.37 kB
✓ built in 638ms
sw.js: QOBIQ — 12 ta, VERSIYA — v6-755dc5daQo'rqmang — har qatorni keyingi darslarda ochamiz. Hozir faqat asosiylarini ko'ring:
tsc -b && vite build— avvaltsctekshiradi, xato bo'lmasa Vite yig'adi.&&— "oldingisi muvaffaqiyatli bo'lsa, keyingisini bajar". Vite turlarni tekshirmaydi — tsc va bundler'lar darsidagi "tekshirish va yozishni ajratish" qoidasi shu.23 modules transformed— 23 ta modul o'girildi. Natijada 3 ta JavaScript va 1 ta CSS fayl chiqdi.gzip: 9.51 kB— gzip — server fayllarni tarmoq orqali yuborishdan oldin siqadigan usul (HTTP sarlavhalari darsidagiContent-Encoding). Vite siqilgan hajmni ham ko'rsatadi, chunki foydalanuvchi aynan shuni yuklab oladi.index-C4s8yKGl.js— nomdagiC4s8yKGl— hash.map: 115.37 kB— source map (manba xaritasi): siqilgan koddagi xatoni manba qatoriga qaytaradigan fayl (Source map'lar).- Ogohlantirish (
can't be bundled) — ataylab qoldirilgan. Uni Bundler nima darsida tushuntiramiz. - Oxirgi qator — Service Worker uchun yozgan o'z plaginimizning xabari (Vite plaginlari).
638ms — vaqt, sizda boshqacha bo'ladi.
4.3 Uch papka: src/, node_modules/, dist/
Har zamonaviy frontend loyihada shu uch papkani ko'rasiz. Ularni adashtirish — boshlovchining eng ko'p uchraydigan xatosi.
| Papka | Ichida nima | Kim yozadi | Git'ga |
|---|---|---|---|
src/ |
Manba kod | Siz | Ha |
node_modules/ |
Paketlar va ularning paketlari | npm install |
Yo'q |
dist/ |
Build natijasi | npm run build |
Yo'q |
node_modules/ va dist/ ni bitta buyruq bilan qayta yasash mumkin, shuning uchun ular .gitignore da turadi. Git'da faqat ularning "retsepti" saqlanadi: package.json, package-lock.json, manba kod va config fayllar.
node_modules/ qancha joy oladi? Biz o'lchadik (du -sm, Windows 11, npm 11.19.0):
| Loyiha | node_modules/ |
|---|---|
vazifalar v5 (bugun) |
86 MB |
vazifalar v6 (16-qism oxirida) |
168 MB |
Bu — asboblarning narxi: Vite, commitlint, husky, knip va ularning bog'liqliklari. Lekin ularning hech biri brauzerga bormaydi — brauzerga faqat dist/ boradi.
Tekshirib ko'ring: Sardor
dist/assets/index-C4s8yKGl.jsfaylini ochib, xatoni o'sha yerda tuzatdi. Ertasiga u yananpm run buildqildi. Tuzatish nima bo'ladi?
Javob
Yo'qoladi. Build dist/ ni har safar boshidan yozadi — manba (src/) dan. dist/ dagi o'zgarish hech qayerga saqlanmaydi. Tuzatish har doim src/ da qilinadi. Bundan tashqari, tarkib o'zgargani uchun yangi buildda fayl nomidagi hash ham boshqacha bo'ladi.
5. vazifalar: bugun va 16-qism oxirida
5.1 Bugungi zanjir — v5
15-qismda vazifalar ga eng sodda zanjirni qurgan edik: tsc har .ts faylni alohida .js ga aylantiradi, nusxala.js qolgan fayllarni ko'chiradi. Haqiqiy chiqish — undagi hajmlar yo'qligiga e'tibor bering: v5 build nima yozganini aytmaydi.
npm run build> prebuild
> node -e "fs.rmSync('dist', { recursive: true, force: true })"
> build
> tsc && node skriptlar/nusxala.js
dist/ ga ko'chirildi: 6 tadist/ da 29 ta fayl. Ulardan 21 tasi JavaScript va CSS. Brauzer sahifani ochganda ulardan 20 tasini alohida so'raydi (turlar.js — build'dan keyin bo'sh modul: undagi turlar faqat import type bilan olinadi). Har modul — alohida so'rov, alohida fayl, ichida izohlar va bo'sh joylar bilan.
Bu yomon emas: Lighthouse 100 edi. Lekin modullar ko'paygan sari so'rovlar ham ko'payadi. npm paketini esa bu zanjir tushunmaydi: brauzer import "web-vitals" ni qayerdan izlashni bilmaydi. Shuning uchun web-vitals ni qo'lda vendor/ papkasiga ko'chirgan edik.
5.2 16-qism oxiridagi zanjir — v6
16-qismda vazifalar 18 ta qadamda yangi zanjirga o'tadi:
flowchart LR
subgraph V5["v5: bugun"]
direction TB
A1["19 ta .ts"] --> A2["tsc: tekshiradi<br/>va yozadi"]
A2 --> A3["dist/: 21 ta<br/>JS va CSS"]
end
subgraph V6["v6: 16-qism oxirida"]
direction TB
B1["src/: 19 ta .ts"] --> B2["tsc -b:<br/>faqat tekshiradi"]
B2 --> B3["vite build: o'giradi,<br/>yig'adi, siqadi"]
B3 --> B4["dist/: 4 ta<br/>JS va CSS"]
end
V5 ~~~ V6Ikki ustunni solishtiring. Chapda (v5) tsc ikki ishni qiladi. O'ngda (v6) ish bo'lingan: tsc faqat tekshiradi, JavaScript'ni Vite yozadi. Eng katta farq pastda: 21 o'rniga 4 ta fayl.
5.3 Raqamlar: qayerga boramiz
Ikkala dist/ ni o'lchadik: brauzer yuklaydigan JavaScript va CSS (Service Worker'siz), xom hajm va gzip (-9) bilan. Bu raqamlarni o'zingiz ham 3-mashqda chiqarasiz.
- v5: tsc, bundlersiz20 ta so'rov32 KB
- v6: tsc -b + vite build4 ta so'rov, −56 %14,3 KB
Manba: O'lchandi: vazifalar v5 va v6 dist/, gzip -9, Node 24.21.0, Vite 8.3.3, 2026-10-07
| v5 (bugun) | v6 (16-qism oxiri) | |
|---|---|---|
| JS + CSS, xom | 85.8 KB | 38.1 KB |
| JS + CSS, gzip | 32.0 KB | 14.3 KB |
| Fayllar (so'rovlar) | 20 | 4 |
| Lighthouse FCP / LCP | 1.3 s / 1.8 s | 1.1 s / 1.5 s |
Oxirgi qator — Lighthouse 13.5.0 ning mobil o'lchovi (Chrome 154, gzip bilan). FCP (birinchi matn yoki rasm chiqqan vaqt) va LCP (eng katta element chiqqan vaqt) ni Core Web Vitals darsidan bilasiz. Ball ikkalasida 100. Lekin sahifa 0.3 soniya tezroq to'liq chiziladi.
Halol bo'laylik: yutuq bepul emas. node_modules/ 86 MB dan 168 MB ga o'sadi, ildizga yangi config fayllar qo'shiladi. Shuning uchun har qadamda so'raymiz: "bu asbob o'z narxini oqlaydimi?". Masalan, 15-qismda Zod'ni "bundler bilan qayta ko'ramiz" degan edik. O'lchaymiz va uch maydonli tekshiruvimizga kutubxona kerak emasligini ko'ramiz (Paket tanlash).
5.4 Minifikatsiya va hash — ko'z bilan
vazifa.ts dagi VazifaXatosi klassi build'dan keyin dist/assets/index-C4s8yKGl.js ichida shunday ko'rinadi (bitta uzun qatorning bir bo'lagi):
var e=class extends Error{kod;constructor(e,t){super(e,t),this.name=`VazifaXatosi`,this.kod=t?.kod??`NOMALUM`}},t=class e{static MAKS_UZUNLIK=100;id;bajarildi;#e;constructor(e,t,n=!1){this.id=e,this.#e=t,this.bajarildi=n}sNimalar o'zgardi:
xabarvasozlama—evatbo'ldi. Ichki nomlar tashqariga ko'rinmaydi, shuning uchun ularni qisqartirish xavfsiz.false—!1bo'ldi (uch belgi kam, ma'nosi bir xil).- Izohlar, bo'sh joylar, qator ko'chishlari — yo'q. Butun fayl bitta qator.
- Xabar matnlari (
"NOMALUM") va xususiyat nomlari (bajarildi) saqlandi — ularsiz dastur buziladi.
Endi hash. Brauzer yuklangan fayllarni keshda saqlaydi, toki keyingi safar qayta yuklamasin. Muammo: siz kodni yangiladingiz, foydalanuvchi esa keshdagi eski app.js ni ishlataveradi. Hash buni yechadi: tarkib o'zgarsa — nom o'zgaradi va brauzer uni yangi fayl deb yuklaydi. Tarkib o'zgarmasa — nom ham o'sha, kesh ishlayveradi. Batafsil — Code splitting va hash bilan keshlash darsida.
5.5 Oxirgi halqa: Pages va CDN
dist/ tayyor. 15-qismdan beri GitHub Actions uni GitHub Pages'ga yuklaydi (Actions orqali deploy). Lekin Pages fayllarni bitta kompyuterdan bermaydi.
CDN (Content Delivery Network — kontent yetkazish tarmog'i) — dunyoning turli shaharlaridagi serverlar to'plami. Ular saytingiz fayllarining nusxasini saqlaydi va foydalanuvchiga eng yaqinidan beradi. CDN'ni Internet darsida qisqa ko'rgansiz. Bu xuddi «Bahor»ning shahar bo'ylab filiallari kabi: mijoz markaziy oshxonaga emas, eng yaqin filialga boradi.
GitHub Pages'dagi istalgan saytning sarlavhalarida buni ko'rish mumkin. Terminaldan tarmoqni tekshirish darsidagi curl -I bilan GitHub'ning o'z Pages sahifasini so'radik (faqat kerakli qatorlar):
curl -sI https://pages.github.com/Server: GitHub.com
Cache-Control: max-age=600
Via: 1.1 varnish
Age: 60
X-Served-By: cache-ams-eham8680022-AMS
X-Cache: HITX-Served-By: cache-ams-…— javobni Amsterdam'dagi (AMS) kesh serveri berdi. Sizda boshqa shahar chiqishi mumkin.X-Cache: HIT— fayl kesh serverda bor edi, asosiy serverga borilmadi.Cache-Control: max-age=600— brauzer faylni 600 soniya (10 daqiqa) eski hisoblamaydi. Pages'da bu qiymatni o'zgartirib bo'lmaydi. Buni hash bilan keshlash darsida yana eslaymiz.
Tekshirib ko'ring: Nega v6 da so'rovlar soni 20 dan 4 ga tushgani muhim, agar har fayl kichik bo'lsa ham?
Javob
Har so'rovning o'z narxi bor: so'rov yuborish, javobni kutish, sarlavhalar. Ayniqsa modullarda brauzer avval bitta faylni oladi, undagi import larni o'qiydi, keyin keyingilarini so'raydi — zanjir bo'lib. Sekin mobil internetda bu kutishlar qo'shilib boradi. Bundler modullarni oldindan birlashtiradi, shuning uchun brauzer hamma kerakli kodni kam so'rov bilan oladi.
6. 16-qism xaritasi
16-qism 48 darsdan iborat. Ularni yetti blokka bo'lish mumkin. Har blok zanjirning bir qismini ochadi va vazifalar ga aniq bir narsa qo'shadi. Jadvaldagi #02 kabi raqamlar — "Vazifalar qadami" bo'lgan darslar.
| Darslar | Blok | vazifalar ga nima qo'shiladi |
|---|---|---|
| 01–02 | Zanjir va Node versiyasi | .nvmrc, engines (#02) |
| 03–19 | npm va paketlar | npm run check (#06), .npmrc va imzo tekshiruvi (#16) |
| 20–25 | Bundler asoslari | vite build (#20), brauzerlar ro'yxati (#22), source map (#24) |
| 26–32 | Vite | dev va preview (#26), .env (#28), src/ (#29), tahlil (#30), o'z plagini (#31), proxy (#32) |
| Darslar | Blok | vazifalar ga nima qo'shiladi |
|---|---|---|
| 33–35 | Boshqa bundlerlar va SVG | — (o'qish va mashq) |
| 36–41 | Kod sifati asboblari | tur bilan ishlaydigan ESLint (#38), commitlint (#40), Git hook'lar (#41) |
| 42–48 | Config fayllar va orientatsiya | tsconfig bo'linishi (#42), ildiz fayllari (#44), knip (#48) |
Har blok nimani o'rgatadi:
- npm va paketlar —
package.jsonmaydonlari, versiyalar, lock-fayl, pnpm/Yarn/Bun, paket tanlash va xavfsizlik. - Bundler asoslari — bog'liqlik grafi, polyfill, tree shaking, code splitting — Vite'siz, tushuncha sifatida.
- Vite — config, rejimlar, plaginlar.
vazifalareng ko'p shu yerda o'zgaradi. - Boshqa bundlerlar — eski loyihadagi webpack config'ini o'qish va 2026-yil manzarasi.
- Kod sifati — ESLint va Prettier chuqur, Biome, commit qoidalari, hook'lar.
- Config fayllar — notanish repoga 15 daqiqada "kirish". Sardorning muammosi shu yerda to'liq yechiladi.
To'rt dars (#09, #23, #25, #43) kodni o'zgartirmaydi — ularda faqat o'lchaymiz. React'ga (17-qism) vazifalar aynan 16-qism oxiridagi tuzilmada o'tadi.
7. Ko'p uchraydigan xatolar
7.1 dist/index.html ni ikki marta bosib ochish
Sardor build qildi va dist/index.html ni Explorer'dan ochdi. Sahifa bo'sh, konsolda (yo'l qisqartirildi):
Access to script at 'file:///…/dist/assets/index-C4s8yKGl.js' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: chrome, chrome-experimental-site-token-provider, chrome-extension, chrome-untrusted, data, http, https, isolated-app.Tarjimasi: "null origin'dan skriptga kirish CORS siyosati bilan to'sildi: boshqa manbadan so'rov faqat ro'yxatdagi protokollar uchun ruxsat etilgan" — file: esa ro'yxatda yo'q. Xuddi shu xabar CSS va manifest uchun ham chiqdi.
Sabab: file:// dan ochilgan sahifaning origin'i null (Origin va Same-Origin Policy). Modul skriptlari esa CORS qoidasi bilan yuklanadi. Vite <link> ga ham crossorigin atributini qo'yadi — shuning uchun CSS ham yuklanmadi.
Tuzatish: build natijasini server orqali oching. 16-qismda buning uchun npm run preview qo'shamiz (Vite I). Hozircha VS Code'dagi Live Server ham yetadi.
7.2 node_modules/ ni ko'chirish yoki git'ga qo'shish
168 MB ni arxivlash shart emas. Bundan tashqari, ba'zi paketlar operatsion tizimga xos tayyor dastur (binar) o'rnatadi: Windows'dagi node_modules Linux'da ishlamasligi mumkin. To'g'ri yo'l: package.json va package-lock.json ni bering, u yerda npm ci qilinsin (Lock-fayllar va npm ci).
7.3 "Build o'tdi — demak hammasi to'g'ri"
Vite turlarni tekshirmaydi: tsc siz build tur xatosi bilan ham "muvaffaqiyatli" bo'ladi. 16-qismda yana bir misol ko'ramiz: .env.production o'chirilsa, build o'tadi, lekin saytda API manzili undefined (Vite III: env). Asbob faqat o'ziga aytilganini tekshiradi — shuning uchun tekshiruvchilar alohida halqa.
8. Mashqlar
1-mashq (oson): Halqani toping
Har ish uchun zanjirning qaysi halqasi javob beradi?
import "web-vitals"dagi paketni internetdan yuklab olish — .price: numberdan: numberni olib tashlash — .- 23 ta modulni 3 ta faylga birlashtirish — .
xabarnominiega qisqartirish — .- Fayl nomiga
C4s8yKGlqo'shish — .
Yechim
- Paket menejeri (npm) —
node_modules/ga yuklaydi. - Transpiler (Vite ichida Oxc).
tscham buni qila oladi, lekin v6 da u faqat tekshiradi. - Bundler (Vite ichida Rolldown).
- Minifikator (Vite 8 da sukut bo'yicha Oxc).
- Hash — Vite fayl tarkibidan hisoblaydi.
E'tibor bering: 2–5 ning hammasini bitta buyruq — vite build qiladi. Vite — bitta asbob emas, zanjirning bir nechta halqasini birlashtirgan "kombayn".
2-mashq (o'rta): v5 dist/ ni o'rganing
O'z vazifalar loyihangizda (15-qism oxiridagi holat):
npm run buildni bajaring.dist/da nechta fayl borligini sanang. Git Bash'da:find dist -type f | wc -l(findfayllarni topadi,wc -lqatorlarni sanaydi).dist/assets/js/vazifa.jsni oching. Manbavazifa.tsdan nimasi bilan farq qiladi?dist/index.htmlni Live Server bilan oching, DevTools → Network → JS filtri. Nechta JavaScript fayli yuklandi?
Yechim
1–2. Bizning loyihada find dist -type f | wc -l — 29. Ulardan 20 tasi .js (vendor/web-vitals.js bilan), bittasi .css, bittasi sw.js; qolgani index.html, manifest va 5 ta ikon.
tscturlarni olib tashlagan, qatorlarni 4 bo'sh joy bilan surgan. Izohlar va nomlar saqlangan — fayl o'qiladigan holda qolgan. Minifikatsiya yo'q.Network'da JS fayllari — 19 ta:
turlar.jsso'ralmaydi (build'dan keyin u bo'sh modul). CSS bilan — 20 ta. Son farq qilsa, "Disable cache" ni yoqib qayta yuklang.
3-mashq (qiyin): O'lchov skripti
kurs/mashqlar/16/01-hajm/ papkasida ikki fayl yozing:
hajm.mjs—measureAssets(dir)funksiyasini eksport qiladi. U papkadagi (ichki papkalar bilan) hamma.jsva.cssfaylni topadi,sw.jsdan tashqari. Har fayl uchun xom hajmni va gzip hajmini hisoblaydi. Natija:{ files: [{ name, raw, gzip }], total: { raw, gzip } }.olcha.mjs— buyruq qatoridan papka oladi, har fayl va jamini chiqaradi.
Keyin node olcha.mjs <vazifalar>/dist bilan o'z v5 loyihangizni o'lchang.
Ishoralar:
readdirSync(dir, { recursive: true })— ichki papkalar bilan hamma nomni qaytaradi. Windows'da yo'l\bilan keladi —replaceAll("\\", "/")bilan tekislang.gzipSync(bytes, { level: 9 })—node:zlibmodulidan: baytlarni gzip bilan siqadi va siqilgan baytlarni qaytaradi.level: 9— eng kuchli siqish..length— siqilgan hajm.process.argv[2]— buyruq qatoridagi birinchi argument (15-qismdagi skriptlardan tanish).- Funksiyani
node:testbilan sinang: vaqtinchalik papka yasab (mkdtempSync), ichiga ma'lum hajmli fayllar yozing.
Yechim
hajm.mjs:
// hajm.mjs — papkadagi .js va .css fayllar hajmi: xom va gzip
import { readdirSync, readFileSync, statSync } from "node:fs";
import { join } from "node:path";
import { gzipSync } from "node:zlib";
// sw.js sahifa bilan birga yuklanmaydi — hisobga olmaymiz
export function measureAssets(dir) {
const names = readdirSync(dir, { recursive: true })
.map((name) => name.replaceAll("\\", "/"))
.filter((name) => /\.(js|css)$/.test(name) && name !== "sw.js")
.filter((name) => statSync(join(dir, name)).isFile())
.sort();
const files = names.map((name) => {
const bytes = readFileSync(join(dir, name));
const gzip = gzipSync(bytes, { level: 9 }).length;
return { name, raw: bytes.length, gzip };
});
const total = { raw: 0, gzip: 0 };
for (const file of files) {
total.raw += file.raw;
total.gzip += file.gzip;
}
return { files, total };
}olcha.mjs:
// olcha.mjs — ishlatish: node olcha.mjs <papka>
import { measureAssets } from "./hajm.mjs";
const dir = process.argv[2];
if (!dir) {
console.error("Papka bering: node olcha.mjs ../vazifalar/dist");
process.exit(1);
}
const { files, total } = measureAssets(dir);
for (const file of files) {
const raw = String(file.raw).padStart(7);
const gzip = String(file.gzip).padStart(7);
console.log(`${file.name.padEnd(32)}${raw}${gzip}`);
}
const kb = (bytes) => (bytes / 1000).toFixed(1);
console.log(
`JAMI: ${files.length} fayl, ${kb(total.raw)} KB, ` +
`gzip ${kb(total.gzip)} KB`,
);statSync(…).isFile() — papka nomlarini (assets/js kabi) tashlab yuboradi: readdirSync ularni ham qaytaradi. .sort() — chiqish har kompyuterda bir xil tartibda bo'lsin.
Bizning v5 dist/ da (boshi va oxiri):
assets/css/vazifalar.css 4734 1661
assets/js/api.js 4507 1757
assets/js/asosiy.js 20686 6454
…
assets/js/vazifa.js 1301 570
assets/js/vendor/web-vitals.js 9027 3376
JAMI: 21 fayl, 85.8 KB, gzip 32.0 KBDarsdagi 85.8 va 32.0 KB aynan shu. Eng katta modul — asosiy.js (20.7 KB), ikkinchisi — render.js (12.6 KB). Sizning raqamlaringiz kodingizga qarab biroz farq qiladi. Bu skriptni saqlab qo'ying: Bundler nima darsida uni v6 dist/ ga ham ishlatasiz va JAMI: 4 fayl, 38.1 KB, gzip 14.3 KB ni o'z ko'zingiz bilan ko'rasiz.
Test (hajm.test.mjs) — node --test hajm.test.mjs:
// hajm.test.mjs — node --test hajm.test.mjs
import { test } from "node:test";
import assert from "node:assert/strict";
import {
mkdtempSync,
mkdirSync,
writeFileSync,
rmSync,
} from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { measureAssets } from "./hajm.mjs";
test("faqat .js va .css; sw.js va boshqalar sanalmaydi", () => {
const dir = mkdtempSync(join(tmpdir(), "hajm-"));
mkdirSync(join(dir, "assets"));
writeFileSync(join(dir, "assets", "app.js"), "a".repeat(1000));
writeFileSync(join(dir, "assets", "app.css"), "b{}");
writeFileSync(join(dir, "sw.js"), "c".repeat(500));
writeFileSync(join(dir, "index.html"), "<p>salom</p>");
const { files, total } = measureAssets(dir);
rmSync(dir, { recursive: true });
assert.deepEqual(
files.map((file) => file.name),
["assets/app.css", "assets/app.js"],
);
assert.equal(total.raw, 1003);
// 1000 ta bir xil harf gzip'da juda qisqaradi
assert.ok(files[1].gzip < 50);
});ℹ tests 2
ℹ pass 2
ℹ fail 0(Ikkinchi test — bo'sh papka uchun nol. Uni o'zingiz yozing.) kurs/mashqlar papkasidan:
git add 16/01-hajm
git commit -m "16/01: hajm.mjs — dist/ dagi JS va CSS o'lchovi"9. Real ishda
- Vakansiyalarda shu zanjir so'raladi: "Vite", "webpack", "npm/pnpm", "ESLint", "CI/CD". Ishdagi birinchi haftangizda
package.jsondagiscriptsva ildizdagi config fayllarni o'qiysiz — 16-qism shunga tayyorlaydi. - React loyihasi (17-qism) aynan shu zanjir bilan yaratiladi:
npm create vite@latest. Next.js'ning (23-qism) zanjiri boshqa, lekin halqalar o'sha. - Intervyu savollari: "Bundler nima va nega kerak?", "Dev va build farqi?", "Fayl nomidagi hash nima uchun?", "Nega
node_modulesgit'ga qo'shilmaydi?".
Xulosa
- Brauzer faqat oddiy JavaScript, CSS va HTML'ni bajaradi:
.ts— MIME yoki sintaksis xatosi,.jsx—Unexpected token '<'. - Asboblar zanjiri: paket menejeri → tekshiruvchilar → transpiler → bundler → minifikator va hash → deploy va CDN. Vositalarning hammasi Node'da ishlaydi.
- Dev server fayllarni so'ralganda o'giradi (tez, HMR bilan), build esa bir marta to'liq yig'ib
dist/ga yozadi. src/— siz yozasiz va git'ga kiradi;node_modules/vadist/— buyruq yasaydi, git'ga kirmaydi.vazifalar16-qismda v5 → v6: JS + CSS 85.8 → 38.1 KB, gzip 32.0 → 14.3 KB, fayllar 20 → 4 — narxinode_modules86 → 168 MB.
Keyingi dars: Node versiya menejerlari: nvm, fnm, Volta va .nvmrc — zanjirning birinchi halqasi: hamma dasturchi va CI bir xil Node versiyasida ishlashi uchun vazifalar ga .nvmrc va engines qo'shamiz.
Manbalar
- Vite hujjatlari: "Why Vite", "Building for Production" — vite.dev/guide/
- Rolldown — rolldown.rs; Oxc — oxc.rs
- MDN: "MIME types", "JavaScript modules" (modul skriptlari va CORS) — developer.mozilla.org
- GitHub Docs: "About GitHub Pages" — docs.github.com/pages
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!