IlmHamroh
JavaScript Full-stack/30-qism. NestJS53/65-dars17 daqiqa
Mundarija (27)

NestJS prodakshnda: build, SWC, prod hajmi va Express bilan o'lchov

Qisqacha: Prodakshnda Nest ilovasi nest build bilan dist/ ga yig'iladi va node dist/main.js bilan ishlaydi. SWC builder tsc'dan ~3× tez yig'adi, lekin .ts kengaytmali importlarni qayta yozmaydi — vazifalar-api SWC bilan ishga tushmadi, shuning uchun tsc qoldi. Kanon o'lchovida Nest versiyasi Express versiyasidan prod hajmda 89 → 152 MB, sovuq startda 2.5 → 4.8 s, GET so'rovlarda ~28–37 % sekinroq; bazani qulflaydigan PATCH'da farq yo'q. Bu darsda loyihaning check skriptiga build va qamrov (coverage) tekshiruvi qo'shiladi.

Bu darsda

  • nest build va SWC builder farqini, SWC nega vazifalar-api da ishlamaganini tushuntirasiz.
  • Prod o'rnatish hajmi nimadan iboratligini o'qiysiz.
  • Express va Nest versiyalarining o'lchovini to'g'ri talqin qilasiz: qayerda farq bor, qayerda yo'q.
  • enableShutdownHooks, helmet, compression va kuzatuv vositalari bo'yicha kanon qarorlarini bilasiz.
  • npm run check ga build va test:qamrov ni qo'shasiz.

Oldin bilishingiz kerak: Nest CLI va loyiha tuzilmasi, Lifecycle hook'lar, Fastify adapter bilan NestJS, Coverage va test sifati metrikalari, Server timeout'lari va keep-alive.

O'tgan darsda vazifalar-api ga HTTP'siz buyruq qo'shdik. Ilova to'liq: HTTP API, buyruq, testlar. Endi uni ishlab turgan serverga chiqarishdan oldingi savollarga javob beramiz: qanday yig'iladi, qancha joy oladi, qanchalik tez va xatolarni kim ushlaydi.

1. Nega bu kerak?

Ishlab chiqishda (npm run start:dev) hamma narsa qulay: kod o'zgarsa qayta yig'iladi, loglar rangli, xato bo'lsa ekranda ko'rasiz. Prodakshnda boshqa talablar:

  • Tez ishga tushish — server qayta ishga tushganda yoki yangi nusxa qo'shilganda.
  • Kichik hajm — Docker image har deploy'da yuklanadi (Dockerfile yozish).
  • To'g'ri to'xtash — SIGTERM kelganda boshlangan so'rovlar tugasin (Server timeout'lari va keep-alive).
  • Ishonch — testda o'tgan kod build'dan keyin ham ishlasin.

25–27-qismlarda Express versiyasi bularning ko'pini hal qilgandi. Nest'ga ko'chish ularni qanday o'zgartirdi — shuni o'lchov bilan ko'ramiz.

O'xshatish: to'y oshi. Uyda bir qozon osh — tez va oson. To'yda 500 kishiga — boshqa ish: qozon kattaligi, o'tin miqdori, vaqt hisobi, kim nima qiladi. Retsept bir xil, lekin tayyorgarlik boshqa.

2. Build: tsc va SWC

2.1 nest build

Nest kodida dekoratorlar va emitDecoratorMetadata bor — Node uni to'g'ridan bajara olmaydi, build shart (Nest CLI va loyiha tuzilmasi). nest build sukut bo'yicha TypeScript kompilyatori (tsc) bilan yig'adi. Kanon o'lchovi (loyihaning unit testlar qo'shilgan bosqichi, bitta mashina). Har qatorda: chiqish kodi, vaqt, dist/ hajmi va fayllar soni; oxirgi ikki qator — build'dan keyin ilova ishga tushdimi:

text
## build: nest build (tsc) vs --builder swc (vazifalar-api nusxasi, unit va e2e testlardan keyingi holat)
tsc #1: exit 0, 16581 ms, dist 902K, js 67
tsc #2: exit 0, 15877 ms, dist 902K, js 67
swc #1: exit 0, 4594 ms, dist 1.4M, js 68
swc #2: exit 0, 5357 ms, dist 1.4M, js 68
tsc build ishga tushdi: 2695 ms (Node fetch bilan kutish), GET /v1/teglar 200
swc build ishga tushdi: timeout ms (kutish); node:internal/modules/esm/resolve:272     throw new ERR_MODULE_NOT_FOUND(           ^  Error [ERR_MODULE_NOT_FOUND]: Cannot find module 'C:\loyiha\vazifalar-api\dist\config.

Raqamlar:

tsc SWC
Yig'ish vaqti 15.9–16.6 s 4.6–5.4 s
dist/ hajmi 902 KB, 67 fayl 1.4 MB, 68 fayl
Ishga tushdimi ha, 2.7 s yo'q

SWC (Speedy Web Compiler) — Rust'da yozilgan TypeScript/JS kompilyatori. U tip tekshirmaydi, faqat o'giradi — shuning uchun tez. Nest CLI uni nest build --builder swc yoki nest-cli.json dagi "builder": "swc" bilan ishlatadi (@swc/cli va @swc/core paketlari kerak).

2.2 Nega SWC ishlamadi

Xato oxiri kesilgan, lekin ma'nosi aniq: Cannot find module '…\dist\config. — keyin ts turadi. "dist/config.ts moduli topilmadi".

vazifalar-api da importlar .ts kengaytmali: import { configYukla } from "./config.ts". Bu 24-qismdan beri kelishuv — Node type stripping bilan .ts faylni to'g'ridan bajaradi (TypeScript'ni Node'da to'g'ridan ishga tushirish). Build paytida tsc rewriteRelativeImportExtensions sozlamasi bilan .ts ni .js ga qayta yozadi. SWC esa bu sozlamani bilmaydi: import satri o'zgarmaydi, dist/ da esa config.ts yo'q, config.js bor.

Kichik model (brauzerda ishlaydi):

js
// tsc (rewriteRelativeImportExtensions) va SWC import yo'llari bilan
// nima qiladi — dist/ da qaysi fayl qidiriladi
const manba = 'import { configYukla } from "./config.ts";';
const tscOgirish = (q) =>
  q.replace(/(from "\.{1,2}\/[^"]+)\.ts"/, '$1.js"');
const swcOgirish = (q) => q; // nisbiy yo'l o'zgarmaydi

const dist = new Set(["config.js", "main.js"]);
const ogiruvchilar = [["tsc", tscOgirish], ["swc", swcOgirish]];
for (const [nom, ogir] of ogiruvchilar) {
  const qator = ogir(manba);
  const fayl = qator.match(/"\.\/([^"]+)"/)[1];
  console.log(`${nom}: ${qator}`);
  console.log(`  dist/${fayl} —`, dist.has(fayl) ? "bor" : "YO'Q");
}

Konsolda:

text
tsc: import { configYukla } from "./config.js";
  dist/config.js — bor
swc: import { configYukla } from "./config.ts";
  dist/config.ts — YO'Q

Model faqat bitta qatorni o'giradi; haqiqiy kompilyator butun faylni tahlil qiladi. Lekin farq aynan shu yerda.

SWC'ni ishlatish uchun importlar .js kengaytmali bo'lishi kerak — Nest hujjati shunday yozadi (./app.module.js). Kanon tanlovi: 25–27 kodi bilan izchillik uchun .ts importlar va tsc qoladi. 16 s build — kichik loyiha uchun chidasa bo'ladigan narx. Katta monorepoda build daqiqalarga cho'zilsa, .js importlarga o'tib SWC'ni yoqish mantiqli.

Tekshirib ko'ring: SWC tip tekshirmaydi. SWC bilan build qiladigan loyihada tip xatolari qayerda ushlanadi?

Javob

Alohida qadamda: tsc --noEmit (npm run tip) — CI'da yoki check skriptida. SWC faqat o'giradi; tip xatosi bo'lsa ham dist/ yaratiladi. Shuning uchun SWC bilan ishlaydigan jamoalar tip ni majburiy tekshiruv qiladi. Nest CLI'da --type-check bayrog'i ham bor — u SWC yonida tsc'ni parallel yurgizadi.

3. Prod hajmi

Prodakshnda dev bog'liqliklar (TypeScript, Vitest, ESLint, Nest CLI) kerak emas. Kanon prod o'rnatishni alohida o'lchadi:

bash
npm ci --omit=dev --omit=optional --ignore-scripts
text
omit dev+optional: exit 0, 152 MB, paketlar 167
72	node_modules/@prisma
14	node_modules/es-toolkit
12	node_modules/swagger-ui-dist
12	node_modules/@redis
9	node_modules/rxjs
8	node_modules/zod
5	node_modules/luxon
5	node_modules/@nestjs

Ustunlar: megabayt va papka. 27-qismdagi Express versiyasi — 89 MB edi. Qayerdan 63 MB qo'shildi?

Prod node_modules: eng katta papkalar
  • @prisma27-qismdan, o'zgarmagan72 MB
  • es-toolkit@nestjs/config bog'liqligi14 MB
  • swagger-ui-dist/docs sahifasi12 MB
  • @redis27-qismdan12 MB
  • rxjsNest yadrosi9 MB
  • @nestjs/*hamma Nest paketlari5 MB

Manba: Kanon o'lchovi (IlmHamroh, 2026-10-28): npm ci --omit=dev --omit=optional, jami 152 MB, 167 paket

Grafikka qarang: Nest paketlarining o'zi atigi 5 MB. Qo'shimcha hajmni Nest ekotizimining bog'liqliklari beradi: @nestjs/config olib kelgan es-toolkit (14 MB), Swagger UI (12 MB), RxJS (9 MB). Eng kattasi — Prisma (72 MB) — 27-qismdan beri bor.

Bog'liqliklar soni ham o'sdi: prod — 10 dan 22 ga, lock fayldagi paketlar — 527 dan 701 ga. Har paket — yangilash, xavfsizlik tekshiruvi va "7 kun qoidasi" bo'yicha kuzatiladigan narsa.

4. Express va Nest: o'lchov

4.1 Shart

Kanon ikki versiyani bitta mashinada, bir xil sozlama bilan yonma-yon yurgizdi: Express (27-qism yakuni) va Nest (shu qism, unit testlar qadami). NODE_ENV=production, SAQLASH=postgres, autocannon. Mashina qattiq band edi — mutlaq req/s past va keng oraliqli, nisbat muhim.

text
sovuq start (ishga tushirishdan birinchi 200 gacha, ms) express: 2506 2518 2472 2481 2513 → mediana 2506
sovuq start (ishga tushirishdan birinchi 200 gacha, ms) nest: 5263 4757 4747 4722 5279 → mediana 4757

Express versiyasi build'siz, Node type stripping bilan ishlaydi; Nest — dist/ dan. Nest ikki baravar sekin ishga tushdi: modul daraxtini yig'ish, metama'lumotni o'qish, Prisma va Swagger hujjatini qurish.

4.2 So'rovlar

Nest / Express, Postgres bilan (Express = 100 %)
  • GET ro'yxat (limit=20)702 → 469 req/s67 %
  • GET bitta vazifa825 → 555 req/s67 %
  • GET teglar845 → 606 req/s72 %
  • POST 422 (validatsiya)1 154 → 880 req/s76 %
  • PATCH (qator qulfi)71 → 69 req/s97 %

Manba: Kanon o'lchovi (IlmHamroh, 2026-10-28): NODE_ENV=production, SAQLASH=postgres, autocannon, bitta mashina, bir vaqtda, mashina band

Uchta xulosa:

  1. O'qish so'rovlari ~28–33 % sekin. Fastify adapter darsidagi "hello world" da Nest qatlami −15 % edi. Bu yerda ko'proq, chunki vazifalar-api ning zanjiri uzun: CLS middleware, nestjs-pino bog'lash, eskirgan yo'l va idempotentlik middleware'lari, global guard, pipe, interceptor va filtr, Standard Schema pipe. Har qatlam kichik narx oladi. Qaysi qatlam qancha olishi — kanon profil qilmagan.
  2. Xato yo'li (422) ~24 % sekin — validatsiya va Problem Details ikkalasida ham bor, Nest qatlamlari qo'shiladi.
  3. PATCH'da farq yo'q (71 va 69). Har PATCH qatorni qulflaydi va bitta vazifani yangilaydi; so'rovlar baza navbatida turadi. HTTP qatlami qanchalik tez bo'lmasin, cheklov — bazada.

Bitta GET /v1/vazifalar/1 so'rovi o'tadigan zanjir (Request lifecycle tartibida):

Bo'g'in vazifalar-api da
middleware so'rov ID, log, CLS, helmet, cors, JSON parser, eskirgan yo'l, idempotentlik
guard JsonTanaGuard (415)
interceptor VazifaSarlavhalariInterceptor (handler'dan keyin ETag, Last-Modified)
pipe SxemaPipe (Standard Schema)
handler VazifalarController → VazifalarService
xato filtri ProblemDetailsFilter

Express versiyasida bu ishlarning ko'pi ham bor edi, lekin oddiy middleware va funksiyalar sifatida. Nest ularni alohida bo'g'inlarga ajratdi va har bo'g'in uchun kontekst (ExecutionContext), metama'lumot o'qish va Observable o'rami qo'shdi. Narx shu ajratishda.

Xotira ombori bilan (bazasiz) o'lchov ham bor: GET ro'yxat 1 151 → 724 req/s (−37 %). Baza yo'q joyda Nest narxi yanada ko'rinadi.

4.3 Bu raqamlar nima demaydi

Bu o'lchovdan "Nest sekin, ishlatmang" degan xulosa chiqmaydi. To'g'ri o'qish:

  • Bitta jarayon soniyasiga 469 ta ro'yxat so'roviga javob beradi (band mashinada). Kuniga bir necha ming foydalanuvchili ilova uchun bu katta zaxira.
  • Yozadigan so'rovlarda (PATCH) farq yo'q — haqiqiy yuk ko'pincha bazada.
  • Nest'ning narxi evaziga: modullar, DI, test qulayligi, Swagger, standart tuzilma. 50 ta dasturchili jamoada bu muhimroq.

Kod hajmi ham o'sdi: src/ 2 653 → 3 281 qator (35 → 55 fayl), testlar 1 742 → 2 133 qator. Fayllar ko'paydi — har modul, controller va xizmat alohida.

O'lchov Express (27) Nest (30)
Prod hajm 89 MB 152 MB
Prod bog'liqliklar 10 22
Sovuq start 2.5 s 4.8 s
GET (Postgres) asos −28…−33 %
PATCH (Postgres) asos farqsiz

Tekshirib ko'ring: Ilova 3 ta nusxada ishlaydi va har biri 4.8 s da ishga tushadi. Yangi versiya deploy qilinganda foydalanuvchilar uzilish sezadimi?

Javob

To'g'ri sozlangan bo'lsa — yo'q. Nusxalar navbat bilan almashtiriladi (rolling update): yangisi /health/ready da tayyor bo'lgandan keyingina eskisi to'xtatiladi (Health check'lar). 4.8 s faqat deploy vaqtini uzaytiradi. Bitta nusxa bo'lsa — 4.8 s uzilish bo'ladi; shuning uchun prodakshnda kamida ikki nusxa ishlatiladi (33–34-qismlar).

5. Shutdown, helmet, compression

5.1 enableShutdownHooks — kanonda yo'q

Nest hujjati prodakshn uchun app.enableShutdownHooks() ni tavsiya qiladi: SIGTERM kelganda Nest onModuleDestroy, beforeApplicationShutdown, onApplicationShutdown hook'larini chaqiradi. vazifalar-api buni ishlatmaydi. Sababi main.ts izohida:

ts
// Signal (SIGTERM/SIGINT) va "let it crash" — o'zimizniki
// (jarayon.ts): avval HTTP ulanishlar to'g'ri yopiladi (yop — bo'sh
// keep-alive'lar darhol), keyin app.close() — Nest lifecycle
// hook'lari (OmborModule: pool va Redis). app.enableShutdownHooks()
// ISHLATILMAYDI — signal ikki joyda ushlanib, yopish ikki marta
// boshlanmasin
jarayonniBoshqar(server, {
  info: (x) => { log.info(x); },
  fatal: (x, xato) => { log.fatal({ err: xato }, x); },
}, { oxirida: () => app.close() });

Tartib muhim: avval HTTP server yangi ulanishlarni qabul qilmaydi va boshlangan so'rovlar tugaydi, keyin baza pool'i yopiladi. Teskari tartibda tugamagan so'rov yopiq pool'ga uriladi. 25-qismda yozilgan drenaj (jarayon.ts, yopish.ts) shu tartibni beradi (Lifecycle hook'lar darsida o'lchangan). enableShutdownHooks qo'shilsa, signal ikki joyda ushlanadi.

5.2 Helmet bor, compression yo'q

  • helmet — xavfsizlik sarlavhalari, 25-qismdan beri Express middleware sifatida (Helmet va xavfsizlik header'lari). Nest'da ham app.use(helmet(...)).
  • compression — javobni gzip/brotli bilan siqish. Kanonda yo'q — 25-qism qarori: siqishni reverse proxy (nginx) qiladi, Node jarayoni CPU'ni JSON uchun sarflasin (Reverse proxy orqasida Node).

5.3 Kuzatuv vositalari — sinalmagan

Nest ekotizimida prodakshn kuzatuvi uchun vositalar bor:

  • OpenTelemetry — so'rov izlari (trace) va metrikalar standarti; Nest uchun avtomatik instrumentatsiya paketlari bor.
  • @nestjs/observe — Nest jamoasining kuzatuv paketi; nest new shablonidagi AGENTS.md uni tavsiya qiladi.
  • NestJS Devtools — modul grafi va DI'ni brauzerda ko'rsatadigan pullik xizmat.

Kanon bularning hech birini sinamadi — kuzatuv 34-qism mavzusi. Xotira profili (heap snapshot) ham sinalmagan. Bu yerda faqat nomlarini bilib qo'ying.

6. Test qamrovi va check

6.1 Nega check ga build

NestJS unit testlari darsida aytilgandi: Vitest kodni Vite (oxc) bilan o'giradi, build esa tsc bilan. Ular bir xil emas. Kanon shunday holatni topgan: aylanma import Vitest'da o'tadi, build'dan keyin esa ilova TDZ xatosi bilan yiqiladi (Circular dependency, ModuleRef va lazy modullar). Demak "testlar yashil" — "ilova ishlaydi" degani emas.

Yechim — check skriptiga build qo'shish:

json
"check": "npm run tip && npm run lint && npm test && npm run build"

Endi bitta npm run check to'rtta narsani tekshiradi: tiplar, lint, testlar va build. Build'dagi xato ham deploy'dan oldin chiqadi.

6.2 test:qamrov

Qamrov (coverage) — testlar kodning qancha qismini ishlatganini ko'rsatadi (Coverage va test sifati metrikalari). Vitest uchun V8 provider'i alohida paket:

bash
npm i -D --save-exact @vitest/coverage-v8@5.0.5

Versiya Vitest bilan bir xil bo'lishi shart — 5.0.5. package.json dagi skript (qatorlarga bo'lingan — JSON'da u bitta qator):

text
"test:qamrov": "vitest run --coverage
  --coverage.include=\"src/**/*.ts\"
  --coverage.exclude=\"src/generated/**\"
  --coverage.exclude=\"src/main.ts\"
  --coverage.exclude=\"src/buyruq.ts\"
  --coverage.exclude=\"src/**/*.d.ts\"
  --coverage.thresholds.lines=90
  --coverage.thresholds.branches=80
  --coverage.thresholds.functions=90"
  • include — src/ dagi hamma .ts. Bu muhim: testlar umuman chaqirmagan fayl ham hisobotga tushadi va foizni pasaytiradi. 25-qismdagi tuzoq: sanalmagan fayl foizni yolg'on shishiradi.
  • exclude — Prisma generatsiya qilgan kod, kirish nuqtalari (main.ts, buyruq.ts) va tip fayllari.
  • thresholds — chegaralar: satr 90 %, tarmoq 80 %, funksiya 90 %. Pastroq bo'lsa — buyruq xato bilan tugaydi.

6.3 Kanon natijasi

Bazali testlar bilan (Docker'dagi Postgres va Redis), qisqartirilgan:

text
All files          |   91.62 |    82.86 |   93.84 |   95.02 |                   
  config.ts        |     100 |       90 |     100 |     100 | 59                
  ilova.ts         |     100 |      100 |     100 |     100 |                   
  jarayon.ts       |       0 |        0 |       0 |       0 | 10-35             

Ustunlar: ifoda (statement), tarmoq (branch), funksiya, satr va qoplanmagan qatorlar. Yakuniy: satr 95.02 %, tarmoq 82.86 %, funksiya 93.84 % — chegaralardan o'tdi.

jarayon.ts — 0 %. Bu yolg'on nol: uning testi bor (test/jarayon.test.ts), lekin u kodni bola jarayonda ishga tushiradi (unhandledRejection → exit 1 ni tekshirish uchun). Vitest qamrovi bola jarayon kodini ko'rmaydi. 27-qismda node --test uni ham sanardi — shuning uchun o'sha paytdagi raqamlar biroz baland edi (satr 98.82 %). Qamrov foizi sifat o'lchovi emas — testlar nimani tekshirishini bildirmaydi.

7. Ko'p uchraydigan xatolar

Belgi Sabab Davosi
SWC build'dan keyin ERR_MODULE_NOT_FOUND … .ts importlar .ts kengaytmali .js importlar yoki tsc
Testlar o'tdi, prod ilova yiqildi Vite va tsc farqi (aylanma import) check ga build
Prod image katta dev bog'liqliklar ham o'rnatilgan npm ci --omit=dev
SIGTERM'da so'rovlar uziladi pool HTTP'dan oldin yopildi avval server, keyin app.close()
Qamrov foizi baland, xato ko'p test chaqirmagan fayl hisobotda yo'q coverage.include bilan hamma fayl

8. Mashqlar

Mashqlar kurs/mashqlar/30/53-prodakshn/ da.

1-mashq (oson): o'lchovni o'qing

To'ldiring (kanon raqamlari):

  • tsc build ~16 s, SWC ~5 s. SWC necha baravar tez?
  • Prod node_modules dagi eng katta papka:
  • PATCH (Postgres) Express 71, Nest 69 req/s. Farq bormi?
  • Kanon nega SWC'ni ishlatmaydi? Importlar kengaytmali.
Yechim
  • 3 — 15.9–16.6 s va 4.6–5.4 s, taxminan uch baravar.
  • @prisma — 72 MB, 152 MB ning yarmidan ko'pi.
  • yo'q — 3 % — o'lchov xatoligi ichida; cheklov bazada.
  • .ts — SWC rewriteRelativeImportExtensions ni qo'llamaydi.

2-mashq (o'rta): nisbatlar jadvali

Kanon medianalari (req/s, Postgres) obyektda. Har endpoint uchun Nest / Express foizini hisoblab chiqaring va eng katta farqni toping. Format: "GET teglar: 72 %", oxirida "eng katta farq: …". Ishora: reduce bilan eng kichik foizni toping (reduce).

Yechim
js
const o = {
  "GET ro'yxat": [702, 469],
  "GET bitta": [825, 555],
  "GET teglar": [845, 606],
  "POST 422": [1154, 880],
  PATCH: [71, 69],
};

const foizlar = Object.entries(o).map(([nom, [ex, nest]]) =>
  [nom, Math.round((nest / ex) * 100)]);
for (const [nom, f] of foizlar) console.log(`${nom}: ${f} %`);

const eng = foizlar.reduce((a, b) => (b[1] < a[1] ? b : a));
console.log(`eng katta farq: ${eng[0]} (${eng[1]} %)`);

Konsolda:

text
GET ro'yxat: 67 %
GET bitta: 67 %
GET teglar: 72 %
POST 422: 76 %
PATCH: 97 %
eng katta farq: GET ro'yxat (67 %)

reduce teng qiymatlarda birinchisini qoldiradi (b[1] < a[1], <= emas) — shuning uchun "GET ro'yxat". Ro'yxat so'rovida eng ko'p qatlam ishlaydi: sahifalash, kursor, Link sarlavhasi va katta JSON javob.

3-mashq (qiyin): qamrov chegarasi tekshiruvchisi

tekshir(natija, chegaralar) funksiyasini yozing: natija — { satr, tarmoq, funksiya } foizlari, chegaralar — o'sha kalitlar bilan. Har o'tmagan chegara uchun "tarmoq: 78.5 < 80" satrini qaytarsin; hammasi o'tsa — bo'sh massiv. Kanon natijasi va tarmog'i 78.5 bo'lgan variant bilan sinang, natijaga qarab "exit 0" yoki "exit 1" chiqaring.

Yechim
js
function tekshir(natija, chegaralar) {
  return Object.entries(chegaralar)
    .filter(([k, min]) => natija[k] < min)
    .map(([k, min]) => `${k}: ${natija[k]} < ${min}`);
}

const chegaralar = { satr: 90, tarmoq: 80, funksiya: 90 };
const kanon = { satr: 95.02, tarmoq: 82.86, funksiya: 93.84 };
const zaif = { ...kanon, tarmoq: 78.5 };

for (const [nom, n] of [["kanon", kanon], ["zaif", zaif]]) {
  const xatolar = tekshir(n, chegaralar);
  for (const x of xatolar) console.log(`${nom}: ${x}`);
  console.log(`${nom}: exit ${xatolar.length === 0 ? 0 : 1}`);
}

Konsolda:

text
kanon: exit 0
zaif: tarmoq: 78.5 < 80
zaif: exit 1

Vitest --coverage.thresholds.* xuddi shunday qiladi: chegaradan pastda — xabar va exit 1. CI shu kodga qarab birlashtirishni to'xtatadi. Chegara "ko'tarilib boradigan" bo'lishi kerak: hozirgi darajadan biroz past qo'yiladi va yangi kod uni tushirmasligi kuzatiladi.

9. Loyiha qadami: check va test:qamrov

Bu — 2.0.0 qadamining ikkinchi qismi. Birinchisi — o'tgan darsdagi buyruq.ts. Commit — keyingi darsda.

  1. Dev bog'liqlik:
bash
npm i -D --save-exact @vitest/coverage-v8@5.0.5
  1. package.json dagi scripts da check ni almashtiring va test:qamrov ni qo'shing (to'liq matn — «test:qamrov» bo'limida; JSON'da bitta qator):
diff
-    "check": "npm run tip && npm run lint && npm test",
+    "check": "npm run tip && npm run lint && npm test && npm run build",
  1. Tekshiruv:
bash
npm run check
npm run test:qamrov

Lokal bazangiz bo'lmasa, bazali testlar SKIP bo'ladi — qamrov chegaradan past chiqishi mumkin (pg-ombor.ts, prisma-ombor.ts qoplanmaydi). Bu kutilgan: chegaralar bazali to'liq yugurish uchun. Kanon natijasi — «Kanon natijasi» bo'limida. Hali commit qilmang.

10. Real ishda

  • Docker multi-stage build: birinchi bosqichda npm ci + nest build, ikkinchisida faqat dist/ va npm ci --omit=dev. Image hajmi yuzlab MB ga kamayadi. Buni Dockerfile yozish darsida qilamiz.
  • SWC katta Nest loyihalarida keng tarqalgan — ayniqsa start:dev uchun (qayta yig'ish soniyalardan millisoniyalarga tushadi). Shart — .js importlar va alohida tsc --noEmit.
  • Benchmark madaniyati: "framework X Y dan tez" degan maqolalar hello world o'lchaydi. Haqiqiy savol — o'z endpoint'ingizda, o'z bazangiz bilan, ko'p nusxada. Bu darsdagi PATCH qatori — eng muhim raqam.
  • Intervyu: "Nest'ni prodakshnda qanday ishga tushirasiz?", "SWC va tsc farqi?", "Graceful shutdown Nest'da qanday?", "Coverage 100 % bo'lsa xato yo'qmi?".

Xulosa

  • nest build (tsc) ~16 s; SWC ~3× tez, lekin .ts importlarni qayta yozmaydi — kanonda ishga tushmadi, tsc qoldi.
  • Prod hajm 89 → 152 MB: Nest o'zi 5 MB, qolgani ekotizim (config, Swagger, RxJS) va Prisma.
  • Nest o'qish so'rovlarida ~28–33 % sekin, sovuq start 2× uzun; PATCH'da farq yo'q — cheklov bazada.
  • Shutdown — o'z drenajimiz (avval HTTP, keyin app.close()), enableShutdownHooks yo'q; compression — proxy'da.
  • check = tip + lint + test + build; test:qamrov chegaralari 90/80/90, include bilan hamma fayl sanaladi.

Keyingi dars: NestJS versiyalarini yangilash — Nest 10 → 11 → 12 ko'chishlari, Express 5 marshrut sintaksisi, ESM va vazifalar-api 2.0.0 commit'i.

Manbalar

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
NestJS prodakshnda: build, SWC, prod hajmi va Express bilan o'lchov — IlmHamroh