IlmHamroh
JavaScript Full-stack/16-qism. Frontend asboblari: npm, bundlerlar, config43/48-dars14 daqiqa
Mundarija (31)

Path alias: @/ importlarni tsconfig paths va Vite'da sozlash

Qisqacha: Path alias — "../../../lib/narx.ts" o'rniga "@/lib/narx.ts" yozish uchun qisqa nom. U ishlashi uchun har bir vosita uni bilishi kerak: TypeScript (paths), Vite (resolve.alias yoki resolve.tsconfigPaths), testlar uchun Node. Node paths ni bilmaydi — uning o'z standart taxallusi bor: package.json dagi "imports" (#/). vazifalar da alias yo'q: src/ tekis va @/ Node testlarini buzadi (o'lchandi).

Bu darsda

  • Alias qaysi muammoni hal qilishini va qachon kerak emasligini tushuntira olasiz.
  • @/ ni TypeScript va Vite'da sozlaysiz, "build ishlaydi, dev ishlamaydi" tuzog'ini taniysiz.
  • Node testlari @/ ni nega topmasligini va #/ (subpath imports) qanday yechishini ko'rasiz.
  • jsconfig.json, vite-tsconfig-paths va Next'dagi tayyor aliasni o'qiy olasiz.
  • vazifalar da aliasni o'lchab, nega kanonga kirmaganini asoslaysiz.

Oldin bilishingiz kerak: tsconfig app va node, Modullar TypeScript'da, Vite II: vite.config.

1. Nega bu kerak?

Loyiha o'sgan sari papkalar chuqurlashadi. Sardor «Bahor» menyusi sahifasini src/sahifa/menyu/main.ts ga qo'ydi. Narx formatlash funksiyasi esa src/lib/narx.ts da:

ts
import { formatPrice } from "../../lib/narx.ts";

../../ — "ikki papka yuqoriga". Bu yozuvda uch muammo bor:

  • O'qish qiyin. ../../../ ni ko'rib, qaysi papkaga borishini boshda hisoblash kerak.
  • Ko'chirish og'riqli. main.ts ni bir papka chuqurroqqa ko'chirsangiz, undagi hamma nisbiy import buziladi.
  • Bir fayl — har joyda boshqacha. narx.ts ni bir fayl ../lib/narx.ts, boshqasi ../../lib/narx.ts deb chaqiradi.

Path alias (yo'l taxallusi) — loyihadagi papkaga qisqa nom berish: @/ = src/. Shunda hamma joyda bir xil yozuv:

ts
import { formatPrice } from "@/lib/narx.ts";

O'xshatish: manzilni "Chilonzor, 9-kvartal, 3-uy, 2-podyezd" deb aytish o'rniga "«Bahor» oshxonasi" deyish. Taksi haydovchisi (vosita) bu nomni bilsa — yetib boradi. Bilmasa — adashadi. Darsning butun mazmuni shu: har bir vosita taxallusni bilishi kerak.

Modullar TypeScript'da darsida paths ni ko'rgansiz va uning tuzog'ini ham: tsc toza, Node esa Cannot find package '@/lib'. Bugun Vite bilan to'liq rasmni yig'amiz.

2. Kim importni o'qiydi

Bitta import qatorini loyihada kamida uch xil dastur o'qiydi:

flowchart LR
  I["import … from<br/>'@/lib/narx.ts'"] --> T["TypeScript<br/>(tsc, muharrir)"]
  I --> V["Vite<br/>(dev va build)"]
  I --> N["Node<br/>(node --test)"]
  T --> P["tsconfig<br/>paths"]
  V --> A["resolve.alias yoki<br/>tsconfigPaths"]
  N --> J["package.json<br/>imports (#)"]

Uchtasining sozlamasi uch xil joyda. Bittasini unutsangiz, o'sha vosita importni topa olmaydi. ESLint (projectService) TypeScript bilan bir xil ko'radi — u alohida sozlanmaydi.

3. Mustaqil Vite loyihasida @/

3.1 Mashq loyihasi

kurs/mashqlar/16/43-alias/: Vite 8.3.3, TypeScript 7.0.2, index.html, src/sahifa/menyu/main.ts, src/lib/narx.ts va tekshiruv/narx.test.ts (Node testi). narx.ts:

ts
// Narxni "35 000 so'm" ko'rinishiga keltiradi
export function formatPrice(price: number): string {
  const digits = String(price).replace(/\B(?=(\d{3})+$)/g, " ");
  return `${digits} so'm`;
}

console.log(formatPrice(35000)); // 35 000 so'm

Boshlanishda importlar nisbiy, hammasi ishlaydi: npx tsc jim, npx vite build → dist/assets/index-HJIljoLR.js 0.93 kB, node --test → ℹ pass 1.

3.2 Sozlamasiz @/

main.ts dagi importni "@/lib/narx.ts" ga almashtirdik:

bash
npx tsc
text
src/sahifa/menyu/main.ts(1,29): error TS2307: Cannot find module '@/lib/narx.ts' or its corresponding type declarations.

"@/lib/narx.ts moduli yoki uning tur e'lonlari topilmadi". Vite ham topmadi:

text
Error: [vite]: Rolldown failed to resolve import "@/lib/narx.ts" from "D:/kurs/mashqlar/16/43-alias/src/sahifa/menyu/main.ts".
This is most likely unintended because it can break your application at runtime.
If you do want to externalize this module explicitly add it to
`build.rolldownOptions.external`

"Rolldown importni topa olmadi. Ehtimol, bu xato — dastur ishlaganda buzilishi mumkin". Hozircha hamma vosita bir ovozdan "bilmayman" deydi — bu yaxshi, xato darhol ko'rinadi.

3.3 TypeScript: paths

tsconfig.json ning compilerOptions iga:

json
{
  "compilerOptions": {
    "paths": { "@/*": ["./src/*"] }
  }
}
Qism Ma'nosi
"@/*" @/ bilan boshlangan har import; * — qolgan qism
["./src/*"] * ni shu yerga qo'y: @/lib/narx.ts → ./src/lib/narx.ts
massiv bir nechta joy bo'lishi mumkin — TypeScript ularni tartib bilan sinaydi

npx tsc — jim. Endi qiziq joyi.

3.4 Tuzoq: build yashil, dev qizil

Vite'ga hali hech narsa demadik. Lekin:

bash
npx vite build
text
dist/assets/index-HJIljoLR.js  0.93 kB │ gzip: 0.54 kB
✓ built in 86ms

Build o'tdi — va natija nisbiy importdagi bilan bayt-bayt bir xil (hash HJIljoLR). Vite 8.3.3 ning build qismi (Rolldown) tsconfig.json dagi paths ni o'zi o'qidi. Endi dev server — npm run dev va brauzerda sahifani ochamiz. Terminalda:

text
[vite] Internal server error: Failed to resolve import "@/lib/narx.ts" from "src/sahifa/menyu/main.ts". Does the file exist?

"Importni topib bo'lmadi. Fayl bormi?" Dev server (Vite'ning o'z resolver'i) paths ni o'qimaydi. Ya'ni CI'dagi build yashil, sizning kompyuteringizda esa sahifa oq. Bunday holatda "menda ishlamayapti, CI'da ishlaydi" degan bahs boshlanadi.

Qoida: hujjatda yozilmagan xulqqa tayanmang. Vite'ning resolve.tsconfigPaths sozlamasi sukut bo'yicha false (vite/dist/node/index.d.ts: @default false). Build'dagi "o'zi ishladi" — tasodif, kafolat emas.

3.5 Vite: resolve.tsconfigPaths yoki resolve.alias

Vite 8 da ikki to'g'ri yo'l bor. Birinchisi — paths ni Vite'ga ham o'qitish (vite.config.ts):

ts
// vite.config.ts — @/ taxallusini tsconfig.json dagi paths'dan oladi
import { defineConfig } from "vite";

export default defineConfig({
  resolve: {
    // Vite 8: paths'ni dev serverda ham, build'da ham o'qiydi
    tsconfigPaths: true,
  },
});

Dev server endi importni haqiqiy yo'lga aylantiradi — brauzerga boradigan main.ts ning birinchi qatori:

text
import { formatPrice } from "/src/lib/narx.ts";

Ikkinchi yo'l — taxallusni Vite'da alohida yozish:

ts
resolve: {
  alias: { "@": "/src" },
},

resolve.alias — Vite II dagi kalit; vazifalar da u tema.js uchun allaqachon bor. Kamchiligi: taxallus endi ikki joyda (tsconfig va Vite) yoziladi va ular bir-biridan "ajralib" qolishi mumkin. tsconfigPaths: true da manba bitta.

3.6 vite-tsconfig-paths — eski usul

Vite 8 gacha paths ni o'qitish uchun plagin kerak edi: vite-tsconfig-paths (6.1.1). Internetdagi ko'p misollarda u bor. Vite 8.3.3 uni ko'rsa, ogohlantiradi (manba kodidagi xabar):

text
The plugin "vite-tsconfig-paths" is detected. Vite now supports tsconfig paths resolution natively via the resolve.tsconfigPaths option. You can remove the plugin and set resolve.tsconfigPaths: true in your Vite config instead.

"Plagin topildi. Vite endi buni o'zi qiladi — plaginni olib tashlab, resolve.tsconfigPaths: true qo'ying". Eski loyihada uchratsangiz — shu almashtirish.

Tekshirib ko'ring: Jamoa paths qo'shdi, CI'dagi npm run build yashil. Yangi dasturchi npm run dev qildi va oq sahifa ko'rdi. Sabab nima va qanday tuzatiladi?

Javob

Vite 8 build qismi paths ni o'zi o'qidi, dev server esa o'qimaydi — resolve.tsconfigPaths: true (yoki resolve.alias) yozilmagan. Tuzatish — vite.config.ts ga shu sozlama. Saboq: alias qo'shgandan keyin build ni ham, dev ni ham tekshiring.

4. Node: paths ni bilmaydi

4.1 Test yiqiladi

Brauzer kodi ishladi. Endi testda ham @/:

ts
import { formatPrice } from "@/lib/narx.ts";
bash
node --test
text
Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@/lib' imported from D:\kurs\mashqlar\16\43-alias\tekshiruv\narx.test.ts
ℹ pass 0
ℹ fail 1

"@/lib paketi topilmadi". Node @ bilan boshlangan yozuvni scope'li npm paket deb o'qidi (@typescript/native kabi — package.json pasporti): @/lib — "egasi bo'sh, paket lib". U node_modules da qidirdi va topmadi. Node tsconfig.json ni umuman o'qimaydi — tur tekshiruvi uning ishi emas.

4.2 #/: Node'ning o'z taxallusi

Modullar TypeScript'da darsidagi yechim — package.json dagi "imports" maydoni (subpath imports). Nomlar # bilan boshlanishi shart:

bash
npm pkg set 'imports.#/*=./src/*'
json
{
  "imports": {
    "#/*": "./src/*"
  }
}

Importlar "#/lib/narx.ts" bo'ladi — main.ts da ham, testda ham. Natija:

Vosita #/lib/narx.ts
node --test ℹ pass 1
npx tsc (moduleResolution: bundler) jim
npx vite build index-HJIljoLR.js 0.93 kB (bir xil hash)
npm run dev import { formatPrice } from "/src/lib/narx.ts";

Hech qanday paths, alias yoki plaginsiz — hamma vosita tushundi. Sababi: imports — Node standarti, TypeScript va Vite ham uni o'qiydi. Bitta manba, uch o'quvchi.

Diqqat: # dan keyingi qism sizning tanlovingiz: #/*, #src/*, #lib/* — hammasi ishlaydi (vazifalar da #src/* ni ham sinadik). Faqat # ning o'zi majburiy: Node imports ni shu belgidan taniydi.

4.3 @/ yoki #/?

@/ (paths + Vite) #/ (imports)
Sozlama 2 joy (tsconfig, vite.config) 1 joy (package.json)
Node testlari ishlamaydi ishlaydi
Tanishligi React/Next shablonlarida standart kamroq uchraydi
Standart vositalarning kelishuvi Node rasmiy imkoniyati

@/ ni ko'p uchratasiz — shablonlar shunday. #/ esa Node ham ishtirok etadigan loyihada xavfsizroq.

5. Vazifalar: o'lchov (kod o'zgarmaydi)

5.1 @/ sinovi

vazifalar ning o'tgan darsdagi holatida (ikki tsconfig bilan) vaqtincha src/royxat.ts dagi "./vazifa.ts" ni "@/vazifa.ts" ga almashtirdik, tsconfig.app.json ga paths, Vite'ga resolve.alias qo'shdik.

Tekshiruv Natija
npx tsc -b jim (toza)
npx vite build index-C4s8yKGl.js 25.38 kB — alias'siz bilan bir xil
npm test ℹ tests 77 · ℹ pass 71 · ℹ fail 6

Testlar soni ham kamaydi — 146 dan 77 ga: royxat.ts ni import qiladigan test fayllari umuman yuklanmadi. Xato:

text
Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@/vazifa.ts' imported from D:\kurs\vazifalar\src\royxat.ts

vazifalar testlari .ts fayllarni Node 24 da to'g'ridan-to'g'ri ishga tushiradi (type stripping). Node uchun @/vazifa.ts — topilmagan paket.

Yana bir kuzatuv. resolve.alias ni yozmay, faqat paths bilan ham build o'tdi — lekin boshqa hash bilan (index-BEMsr5Bb.js, 25.78 kB). alias yoki tsconfigPaths: true bilan esa natija asl C4s8yKGl ga qaytdi. Bu yana bir dalil: aniq sozlamasiz xulq oldindan aytib bo'lmaydi.

5.2 #/ sinovi

package.json ga "imports": { "#/*": "./src/*" }, importni "#/vazifa.ts":

Tekshiruv Natija
npx tsc -b jim
npx vite build index-C4s8yKGl.js — bir xil
npm test ℹ tests 146 · ℹ pass 146
npx eslint src/royxat.ts jim

5.3 Qaror

vazifalar da alias yo'q. Sabab — o'lchovdan: src/ tekis, 20 ta fayl yonma-yon turadi va hamma import "./x.ts" ko'rinishida. ../ ning o'zi yo'q — alias hal qiladigan muammo bizda yo'q. Qo'shsak, faqat yangi sozlama va yangi tuzoq qo'shiladi.

Kerak bo'lib qolsa (masalan, 17-qismda papkalar chuqurlashsa) — #/: u Node testlarini buzmaydi. Bu dars vazifalar kodini o'zgartirmaydi.

Tekshirib ko'ring: Nega @/ bilan npm test "146 tadan 6 tasi yiqildi" emas, "77 ta test, 6 ta yiqildi" deydi?

Javob

Yiqilgan 6 ta — testlar emas, butun test fayllari: ular royxat.ts ni import qiladi va import bosqichidayoq xato beradi. Node har bunday faylni bitta "yiqilgan test" deb hisoblaydi, ichidagi o'nlab testlar esa umuman ishga tushmaydi. Shuning uchun jami ham kamaydi. Test sonining keskin kamayishi — "nimadir yuklanmadi" degan belgi.

6. Boshqa joylarda uchraydiganlar

6.1 baseUrl — eskirgan

Eski loyihalarda paths yonida "baseUrl": "." turadi. tsconfig chuqur darsidan bilasiz: TypeScript 7 da u olib tashlangan (TS5102: Option 'baseUrl' has been removed). paths dagi yo'llar endi tsconfig fayliga nisbatan — "./src/*", boshida ./ bilan.

6.2 jsconfig.json

TypeScript'siz, sof JavaScript loyihada ham muharrir @/ ni tushunishi kerak (avtomatik to'ldirish, "Go to Definition"). Buning uchun jsconfig.json — aslida allowJs: true li tsconfig. VS Code uni avtomatik o'qiydi:

json
{
  "compilerOptions": {
    "paths": { "@/*": ["./src/*"] }
  },
  "include": ["src"]
}

Bu faqat muharrir uchun. Vite'ga baribir resolve.alias kerak.

6.3 Next.js — tayyor alias

create-next-app 16.4.0 --import-alias "@/*" bilan yaratgan tsconfig.json da:

jsonc
"paths": {
  "@/*": ["./*"]
}

E'tibor bering: ./src/* emas, ./* — loyiha ildizi (shablonda src/ papkasi yo'q). Next paths ni o'zi o'qiydi, alohida sozlama kerak emas. Next'ni 23-qismda o'rganamiz, React + Vite shablonida esa sukut bo'yicha alias yo'q (17-qism).

6.4 Yaxshi amaliyot: bitta taxallus, bitta qoida

Alias foydali, lekin ko'payib ketsa, yangi muammo yaratadi. Ba'zi loyihalarda shunday ro'yxatni uchratasiz: @components/*, @utils/*, @hooks/*, ~/*, @@/*. Yangi dasturchi har importda "bu qaysi papka?" deb sozlamani ochishga majbur. Nisbiy yo'ldan qochib, boshqa chalkashlikka tushdik.

Amaliy qoidalar:

  • Bitta taxallus — @/ (yoki #/), u src/ ni ko'rsatadi. Qolgani shu ichidan: @/components/Button, @/lib/narx.
  • Qo'shni fayl — nisbiy. Bir papkadagi faylga "./narx.ts" qisqa va aniq. Alias uzoq yo'llar uchun.
  • Muharrir bilan kelishing. VS Code avtomatik import qo'shganda qaysi shaklni tanlashini sozlash mumkin: settings.json dagi typescript.preferences.importModuleSpecifier — "shortest" (sukut), "relative" yoki "non-relative". Jamoa qoidasi @/ bo'lsa — "non-relative" (VS Code sozlamalari).
  • Paket nomiga o'xshatmang. @/ dagi / muhim: @lib deb yozsangiz, u haqiqiy npm scope (@lib/…) bilan adashtiriladi.

Tekshirib ko'ring: Malika paths ga "utils/*": ["./src/utils/*"] qo'shdi va import { sana } from "utils/sana.ts" yozdi. Bir oy o'tib jamoa npm'dan utils degan paket o'rnatdi. Nima bo'lishi mumkin?

Javob

Ikki manba bir nomga da'vo qiladi: paths dagi taxallus va node_modules/utils. TypeScript paths ni oladi, Node esa node_modules dagi paketni — vositalar har xil faylni ochadi va xato juda chalkash ko'rinadi. Shuning uchun taxallus paket nomlaridan aniq farq qilsin: @/… yoki #…. # bilan boshlanadigan paket nomi npm'da umuman bo'lmaydi.

7. Ko'p uchraydigan xatolar

Xabar Kim aytadi Davosi
TS2307: Cannot find module '@/…' TypeScript paths
Rolldown failed to resolve import "@/…" Vite build resolve.tsconfigPaths yoki alias
Failed to resolve import "@/…". Does the file exist? Vite dev xuddi shu
ERR_MODULE_NOT_FOUND: Cannot find package '@/…' Node imports (#/)

Yana biri: paths dagi * ni unutish — "@/": ["./src/"] faqat aynan @/ ni almashtiradi, @/lib/narx.ts ni emas. Naqshda ham, manzilda ham * bo'lsin.

8. Mashqlar

1-mashq (oson): kim bilmaydi?

Har xabar qaysi vositadan va unga qaysi sozlama yetishmaydi?

  1. Cannot find package '@/lib' imported from …narx.test.ts —
  2. TS2307: Cannot find module '@/lib/narx.ts' —
  3. Does the file exist? (terminalda npm run dev paytida) —
Yechim
  1. Node — paths ni bilmaydi; yechim #/ (package.json imports).
  2. TypeScript — compilerOptions.paths.
  3. Vite dev server — resolve.tsconfigPaths: true yoki resolve.alias.

2-mashq (o'rta): @/ ni to'liq ulang

kurs/mashqlar/16/43-alias/ da main.ts importini @/lib/narx.ts ga almashtiring. Shunday sozlangki, npx tsc, npx vite build va npm run dev (brauzerda menyu chiqadi) — uchalasi ishlasin. Faqat bitta joyda taxallus yozing.

Yechim

tsconfig.json — "paths": { "@/*": ["./src/*"] }. vite.config.ts:

ts
// vite.config.ts — @/ taxallusini tsconfig.json dagi paths'dan oladi
import { defineConfig } from "vite";

export default defineConfig({
  resolve: {
    // Vite 8: paths'ni dev serverda ham, build'da ham o'qiydi
    tsconfigPaths: true,
  },
});

Taxallus faqat paths da; Vite uni o'qiydi. Tekshiruv: tsc jim, build index-HJIljoLR.js (nisbiy import bilan bir xil), dev'da main.ts → import { formatPrice } from "/src/lib/narx.ts";.

3-mashq (qiyin): testni ham ulang

Endi tekshiruv/narx.test.ts ham @/lib/narx.ts dan import qilsin. node --test nima deydi? Uni shunday tuzatingki, test ham, Vite ham, tsc ham ishlasin — paths va tsconfigPaths siz.

Yechim

@/ bilan: Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@/lib' …, ℹ fail 1. Tuzatish — npm pkg set 'imports.#/*=./src/*' va ikkala faylda "#/lib/narx.ts":

ts
import { formatPrice } from "#/lib/narx.ts";

node --test → ℹ pass 1; npx tsc — jim; npx vite build → index-HJIljoLR.js; dev — ishlaydi. paths va vite.config.ts endi kerak emas — ularni olib tashlang. Bash'da 'imports.#/*=./src/*' ni bitta tirnoqqa oling: aks holda bash * ni papkadagi fayl nomlariga almashtirishga urinadi.

9. Real ishda

  • React + Vite va Next loyihalarida @/components/Button kabi importlar — odatiy manzara. Endi uning ortidagi sozlamalarni bilasiz.
  • Monorepo larda alias o'rniga ko'pincha haqiqiy paket nomlari (@kompaniya/ui) va workspaces ishlatiladi — Node ham, bundler ham ularni bir xil tushunadi.
  • Ko'chirish (migratsiya) paytida — masalan, testlarni Vitest'dan node:test ga — birinchi yiqiladigan narsa @/ importlar bo'ladi.
  • Test vositalari farq qiladi. Vitest (22-qismda) Vite sozlamasini o'zi o'qiydi — resolve.alias u yerda ham ishlaydi. node --test esa Vite'ni bilmaydi va faqat imports ga ishonadi. Testlar qaysi vosita bilan ishlashini bilib, alias turini tanlang.
  • Kod sharhida yangi taxallus qo'shilgan PR'ga "build, dev va test — uchalasini tekshirdingizmi?" degan savol odatiy. Bugungi dars aynan shu savolning javobi.
  • Intervyu: "Nega paths yetarli emas?", "# importlar nima?", "alias'ni qachon qo'shmaslik kerak?".

Xulosa

  • Alias — ../../ o'rniga qisqa nom; uni har bir vosita bilishi kerak: TypeScript (paths), Vite (resolve.tsconfigPaths / resolve.alias), Node (imports).
  • Vite 8.3.3: build paths ni o'zi o'qishi mumkin, dev server — yo'q; aniq sozlang va build hamda dev ni tekshiring.
  • Node @/lib ni npm paket deb qidiradi → ERR_MODULE_NOT_FOUND. "imports": { "#/*": "./src/*" } — Node, tsc va Vite birdek tushunadi.
  • vazifalar: @/ — 77 testdan 6 fayl yiqildi; #/ — 146/146. Kanonda alias yo'q: src/ tekis, ../ yo'q.
  • baseUrl — TS 7 da yo'q; jsconfig.json — JS loyiha muharriri uchun; Next shablonida @/* tayyor.

Keyingi dars: Loyiha ildizidagi fayllar — .env.example, .nvmrc, LICENSE, .gitattributes va .dockerignore: har kichik fayl qaysi xatoning oldini oladi; Windows'dagi CRLF tuzog'i Prettier'ni qanday yiqitadi.

Manbalar

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Path alias: @/ importlarni tsconfig paths va Vite'da sozlash — IlmHamroh