Real loyiha arxitekturasi — papkalar tuzilishi, best practices
Muammodan boshlaylik
Loyiha bir yil oldin boshlangan. Hozir:
app/ichida sahifalar, komponentlar, util lar, API chaqiruvlari aralash- Bir xil Prisma so'rovi 8 ta faylda nusxalangan — biriga ruxsat tekshiruvi qo'shildi, qolganlariga yo'q
components/da 140 ta fayl;Button.tsx,Button2.tsx,NewButton.tsx- Hamma joyda
'use client'— chunki "shunday ishlaydi" - Yangi dasturchi bir haftada ham "qayerga nima yozish kerak"ligini tushunmaydi
Hayotiy o'xshatma
Yaxshi tashkil etilgan oshxona. Har narsaning joyi bor: pichoqlar — bir tortmada, ziravorlar — javonda, xom go'sht va tayyor taom — alohida. Yangi oshpaz birinchi kuniyoq nima qayerdaligini topadi. Tartibsiz oshxonada eng yaxshi oshpaz ham sekin ishlaydi va xato qiladi (xom va tayyor narsa aralashib ketadi — bizda: server va client kodi).
Tavsiya etilgan tuzilma
src/
├── app/ # faqat routing: sahifalar, layout lar, route lar
│ ├── (marketing)/ # route group — ochiq sahifalar (25-dars)
│ │ ├── page.tsx
│ │ └── layout.tsx
│ ├── (dokon)/
│ │ ├── katalog/
│ │ │ ├── page.tsx
│ │ │ ├── loading.tsx
│ │ │ └── _components/ # faqat shu sahifaga xos (_ — route emas)
│ │ └── mahsulot/[id]/
│ ├── (auth)/login/
│ ├── dashboard/
│ ├── api/
│ │ ├── auth/[...nextauth]/route.ts
│ │ └── webhooks/
│ ├── layout.tsx
│ ├── not-found.tsx
│ └── global-error.tsx
│
├── features/ # biznes funksiyalar
│ ├── savat/
│ │ ├── components/ # SavatTugmasi.tsx, SavatRoyxati.tsx
│ │ ├── actions.ts # 'use server' — Server Action lar
│ │ ├── queries.ts # server-only — ma'lumot olish
│ │ ├── schemas.ts # Zod
│ │ └── types.ts
│ ├── mahsulotlar/
│ └── buyurtmalar/
│
├── components/
│ ├── ui/ # shadcn: button, dialog... (52-dars)
│ └── layout/ # Header, Footer
│
├── lib/
│ ├── prisma.ts # singleton (45-dars)
│ ├── dal.ts # talabQil, adminTalabQil (43-dars)
│ ├── env.ts # Zod bilan env (65-dars)
│ └── utils.ts # cn()
│
├── auth.ts, auth.config.ts # Auth.js (38, 42-darslar)
├── middleware.ts
└── instrumentation.ts # OpenTelemetry (74-dars)
Asosiy tamoyillar
1. app/ — faqat routing
// app/(dokon)/katalog/page.tsx — yupqa: ma'lumot olish va yig'ish
import { getMahsulotlar } from '@/features/mahsulotlar/queries'
import { MahsulotlarRoyxati } from '@/features/mahsulotlar/components/MahsulotlarRoyxati'
import { Filtrlar } from '@/features/mahsulotlar/components/Filtrlar'
export default async function Katalog({ searchParams }: { searchParams: Promise<Record<string, string>> }) {
const filtr = await searchParams
const { royxat, jami } = await getMahsulotlar(filtr)
return (
<>
<Filtrlar />
<MahsulotlarRoyxati mahsulotlar={royxat} jami={jami} />
</>
)
}
Sahifa biznes mantiqni bilmaydi — u feature lardan qismlarni yig'adi.
2. Feature bo'yicha guruhlash
Savat bilan bog'liq hamma narsa — features/savat/ da: komponentlar, Server Action lar, so'rovlar, sxemalar. O'zgartirish — bitta papkada; o'chirish — bitta papkani o'chirish.
3. Server va client chegarasi aniq
// features/mahsulotlar/queries.ts
import 'server-only'
import { cache } from 'react'
import { prisma } from '@/lib/prisma'
export const getMahsulot = cache(async (id: string) =>
prisma.mahsulot.findUnique({ where: { id, faol: true }, select: mahsulotDTO })
)
// features/savat/actions.ts
'use server'
import { talabQil } from '@/lib/dal'
// har bir action: auth → Zod → baza → revalidate
queries.ts—server-only, faqat o'qish, DTO (faqat ochiq maydonlar)actions.ts—'use server', har biri o'z ichida ruxsatni tekshiradi'use client'— faqat interaktiv barg komponentlarda
4. Server Component — standart
Sahifa (server)
├── Sarlavha (server)
├── MahsulotMa'lumoti (server)
│ └── SavatgaTugma (client) ← faqat shu interaktiv
└── Sharhlar (server, Suspense ichida)
└── SharhForma (client)
'use client' ni daraxtning iloji boricha pastiga qo'ying — brauzerga kam JavaScript, tezroq sahifa (54-dars).
Ma'lumot oqimi
O'qish: page.tsx ──▶ features/*/queries.ts (server-only, cache, DTO) ──▶ Prisma
Yozish: Client forma ──▶ features/*/actions.ts ('use server')
├── talabQil() — auth va ruxsat
├── Zod — validatsiya
├── Prisma — yozish
└── revalidateTag / revalidatePath
Tashqi: mobil ilova, webhook ──▶ app/api/*/route.ts ──▶ o'sha queries va actions mantiqi
API endpoint lar faqat tashqi mijozlar uchun (31-dars). O'z sahifalaringiz — to'g'ridan-to'g'ri queries va actions.
Xavfsizlik — ro'yxat
- Har bir Server Action va Route Handler —
auth()+ ruxsat (42-dars) - Update/delete —
whereda egasi (47-dars) - Barcha kirish — Zod bilan validatsiya
-
server-only— baza va maxfiy kalitlar bilan ishlaydigan fayllarda - DTO — client ga faqat kerakli maydonlar (46-dars)
-
NEXT_PUBLIC_da maxfiy narsa yo'q (65-dars) - Xavfsizlik header lari, CSP (71-dars)
- Login va SMS ga rate limit (34-dars)
- Webhook lar — imzo tekshiruvi (35-dars)
- Bog'liqliklar yangilangan (Dependabot)
Performance — ro'yxat
- Server Component — standart, client — faqat kerak joyda
-
Promise.all— parallel so'rovlar;Suspense— sekin qismlar - Kesh strategiyasi aniq: statik / ISR / dinamik (59-dars)
-
next/image—sizes, LCP rasmgapriority(57-dars) -
next/font,next/script—lazyOnload(58-dars) - Og'ir client komponentlar —
dynamic(56-dars) - Core Web Vitals kuzatiladi (54-dars)
Sifat — ro'yxat
- TypeScript
strict, ESLint, Prettier - Unit (Vitest) + muhim oqimlar uchun E2E (Playwright)
- CI: lint → tsc → test → build; branch protection (69-dars)
-
error.tsx,not-found.tsx,loading.tsx— muhim segmentlarda - Monitoring: xatolar (Sentry), trace lar (74-dars)
[!TIP] Bu tuzilma — boshlang'ich nuqta, qonun emas. Kichik loyihada
features/siz,app/+components/+lib/yetarli bo'lishi mumkin. Tuzilmani loyiha o'sishi bilan rivojlantiring: "bu faylni qayerga qo'yishni bilmayman" yoki "bir xil kod uchinchi marta nusxalandi" — qayta tuzish vaqti kelganining belgilari.
[!INFO] Muhimi — izchillik. Jamoa qaysi tuzilmani tanlasa ham, uni hamma bir xil qo'llashi kerak. Qoidalarni
READMEyokiCONTRIBUTING.mdda yozib qo'ying va ESLint bilan (masalan,featureslar bir-biriga to'g'ridan-to'g'ri kirmasligi) avtomatik tekshiring.
Tez-tez uchraydigan xatolar
1. Hamma narsa app/ ichida
Komponentlar, util lar va sahifalar aralash — routing tuzilmasi o'qib bo'lmaydigan bo'ladi. app/ — routing; qolgani — features/, components/, lib/.
2. Ma'lumot olish komponentlarda tarqoq
Bir xil so'rov 8 joyda — ruxsat tekshiruvi birida bor, birida yo'q. Bitta queries.ts.
3. Root layout da 'use client'
Butun ilova client komponentga aylanadi — Server Component larning barcha afzalliklari yo'qoladi.
Xulosa
app/ — faqat routing: yupqa sahifalar, route group lar, _components
features/ — biznes funksiyalar: components, actions ('use server'), queries (server-only), schemas
components/ui — umumiy UI; lib/ — prisma, dal, env, utils
Server Component — standart; 'use client' — faqat barg komponentlarda
O'qish — queries (cache, DTO); yozish — actions (auth → Zod → DB → revalidate)
API — faqat tashqi mijozlar uchun
Xavfsizlik, performance va sifat ro'yxatlari; izchillik
Kurs yakunlandi
Tabriklaymiz — Next.js kursini tugatdingiz! Siz App Router va Server Component lardan boshlab rendering strategiyalari, ma'lumot olish, routing, API, autentifikatsiya, ma'lumotlar bazasi, stilizatsiya, performance, testlash, deployment va real loyiha arxitekturasigacha bo'lgan yo'lni bosib o'tdingiz.
Keyingi qadamlar:
- O'z loyihangizni yarating — masalan, shu kursdagi do'kon — va Vercel yoki o'z serveringizga deploy qiling
- TypeScript kursi — turlarni chuqurroq o'rganish
- PostgreSQL kursi — ma'lumotlar bazasini mukammal bilish