Mundarija (26)
- Bu darsda
- 1. Nega bu kerak?
- 2. Node paketni qanday qidiradi
- 2.1 Yuqoriga qarab
- 2.2 Tuzoq: ota papkadagi node_modules
- 3. Hoisting: npm paketlarni qayerga qo'yadi
- 3.1 Ko'tarish
- 3.2 Mos kelmasa — ichma-ich
- 3.3 Dublikatlar: muqarrar va keraksiz
- 4. Fantom bog'liqlik
- 4.1 Nima u
- 4.2 Qachon portlaydi
- 5. ERESOLVE: peer to'qnashuvi
- 5.1 Xabarni o'qish
- 5.2 --legacy-peer-deps ning narxi
- 5.3 To'g'ri yechimlar
- 6. Ikki nusxa React
- 7. Ko'p uchraydigan xatolar
- 8. Mashqlar
- 1-mashq (oson): Daraxtni o'qing
- 2-mashq (o'rta): Arvohni tuting
- 3-mashq (o'rta): Takrorni yo'qoting
- 4-mashq (qiyin): Node qidiruvini takrorlang
- 9. Real ishda
- Xulosa
- Manbalar
node_modules ichida: modul qidirish, hoisting, fantom bog'liqlik va ERESOLVE
Qisqacha: Node
import "ms"ni joriy papkadan boshlab yuqoriga qarab har birnode_modulesda qidiradi. npm esa paketlarni iloji boricha ildizdaginode_modulesga "ko'taradi" (hoisting), mos kelmagan versiyalarni ichma-ich joylaydi. Shu sabablipackage.jsonda yo'q paket hamimportqilinadi — bu fantom bog'liqlik. Peer talablari to'qnashganda npmERESOLVEbilan to'xtaydi.--legacy-peer-depsuni chetlab o'tadi, lekin xato keyinroq, ishlayotgan dasturda chiqadi.
Bu darsda
- Node paketni qaysi papkalarda va qanday tartibda qidirishini ko'rasiz.
- Hoisting, ichma-ich nusxalar va
dedupedbelgisini tushunasiz,npm dedupeishlatasiz. - Fantom bog'liqlikni topasiz va u qachon "portlashini" ko'rasiz.
ERESOLVExabarini qatorma-qator o'qiysiz va--legacy-peer-depsning narxini bilasiz.- Ikki nusxa React muammosini o'z ko'zingiz bilan ko'rasiz.
Oldin bilishingiz kerak: Lock-fayllar va npm ci, package.json II: bog'liqlik turlari, npm buyruqlari chuqur.
1. Nega bu kerak?
vazifalar ning package.json ida 8 ta paket, node_modules da esa 102 ta, hajmi 86 MB. Sardor sinab ko'rdi: ms paketi package.json da yo'q, lekin u ishlaydi:
node --input-type=module \
-e "import ms from 'ms'; console.log(ms('1d'))"86400000Bir kunlik millisekundlar. O'rnatilmagan paket qanday ishladi? Yana bir savol bog'liqlik turlari darsidan qolgan: typescript-eslint ni TypeScript 7 bilan o'rnatib bo'lmadi — ERESOLVE. Internetdagi maslahat esa bitta: "--legacy-peer-deps qo'shing". Qo'shsa nima bo'ladi?
Ikkala javob node_modules ning tuzilishida. Bugun uning ichiga kiramiz.
Maslahat: Chiqishlar 2026-10-10 da Windows 11, Node 24.21.0 va npm 11.19.0 bilan olingan. Yo'l boshi
…bilan qisqartirilgan.
2. Node paketni qanday qidiradi
2.1 Yuqoriga qarab
kurs/mashqlar/16/10-node-modules/kassa/ da src/hisob/vaqt.js:
// vaqt.js — ms paketini ichki papkadan ishlatadi
import ms from "ms";
console.log("2 soat =", ms("2h"), "ms");Fayl ikki papka chuqurlikda, node_modules esa loyiha ildizida. Node qaysi papkalarga qaraydi? require.resolve.paths buni aytadi (src/hisob ichida turib):
node -p "require.resolve.paths('ms')"[
'…\\kurs\\mashqlar\\16\\10-node-modules\\kassa\\src\\hisob\\node_modules',
'…\\kurs\\mashqlar\\16\\10-node-modules\\kassa\\src\\node_modules',
'…\\kurs\\mashqlar\\16\\10-node-modules\\kassa\\node_modules',
'…\\kurs\\mashqlar\\16\\10-node-modules\\node_modules',
'…\\kurs\\mashqlar\\16\\node_modules',
…
'C:\\node_modules',
'C:\\Users\\<ism>\\.node_modules',
'C:\\Users\\<ism>\\.node_libraries',
…
](Ro'yxat qisqartirildi: bizda 17 ta yo'l.) Qoida: joriy papkadan boshlab, har bir ota papkaga node_modules qo'shib, disk ildizigacha. Birinchi topilgani ishlatiladi. Oxirgi uchtasi — eski global papkalar, ularni faqat require ko'radi.
flowchart TD
A["kassa/src/hisob/vaqt.js<br/>import 'ms'"] --> B["src/hisob/node_modules — yo'q"]
B --> C["src/node_modules — yo'q"]
C --> D["kassa/node_modules/ms — bor!"]
D --> E["package.json → exports → fayl"]
C -. "topilmasa" .-> F["ota papkalar … disk ildizi"]
F -.-> G["ERR_MODULE_NOT_FOUND"]Papka topilgach, qaysi fayl ochilishini kirish nuqtalari darsidagi exports va main hal qiladi.
2.2 Tuzoq: ota papkadagi node_modules
"Disk ildizigacha" degani — loyihadan tashqarida ham. Sinov: kassa da picocolors yo'q, rang.js uni import qiladi:
// rang.js — package.json da yo'q paketni import qiladi
import pc from "picocolors";
console.log(pc.green("Osh tayyor"), "| picocolors qayerdan?");Avval ERR_MODULE_NOT_FOUND. Endi bir papka yuqorida (10-node-modules/) npm i picocolors qildik:
node rang.js
node -p "require.resolve('picocolors')"Osh tayyor | picocolors qayerdan?
…\kurs\mashqlar\16\10-node-modules\node_modules\picocolors\picocolors.jsIshladi — loyihaga tegishli bo'lmagan papkadan. npm ls picocolors esa (empty) deydi va 1 bilan tugaydi: npm faqat o'z loyihasini biladi. Bunday xato faqat sizning kompyuteringizda "ishlaydi", CI'da esa — yo'q. Qoida: loyihalarni bir-birining ichiga qo'ymang va uy papkangizda (C:\Users\<ism>) tasodifan npm install qilmang.
Tekshirib ko'ring:
D:\loyihalar\node_modules\vitebor.D:\loyihalar\bahor\da Vite o'rnatilmagan,src/main.jsesaimport "vite"qiladi. Nima bo'ladi?
Javob
Ishlaydi: Node bahor/src/node_modules, bahor/node_modules dan keyin D:\loyihalar\node_modules ga ham qaraydi va Vite'ni topadi. Lekin bu loyiha boshqa kompyuterda sinadi. npm ls vite esa yo'qligini ko'rsatadi. Yechim — npm i -D vite va ota papkadagi node_modules ni o'chirish.
3. Hoisting: npm paketlarni qayerga qo'yadi
3.1 Ko'tarish
Agar har paket o'z bog'liqliklarini o'z papkasiga qo'ysa (eslint/node_modules/debug/node_modules/ms/…), daraxt juda chuqur bo'lardi va bir paket o'nlab marta takrorlanardi. npm 3 dan beri boshqacha: iloji bo'lsa, paketni ildizdagi node_modules ga qo'yadi. Bu hoisting (ko'tarish). O'tgan darslarda ko'rgan deduped belgisi — "takror nusxa qo'yilmadi, ildizdagisi ishlatiladi".
3.2 Mos kelmasa — ichma-ich
kassa da: npm i -E debug@4.4.3 ms@2.0.0. debug o'zi ms@^2.1.3 ni so'raydi, biz esa ildizga 2.0.0 ni qo'ydik:
npm ls mskassa@1.0.0 …\kurs\mashqlar\16\10-node-modules\kassa
+-- debug@4.4.3
| `-- ms@2.1.3
`-- ms@2.0.0
ls node_modules node_modules/debug/node_modulesnode_modules:
debug
ms
node_modules/debug/node_modules:
msIldizda — bizning ms@2.0.0. debug ga u mos emas, shuning uchun 2.1.3 debug ning ichiga qo'yildi. Node qidiruvi buni o'zi hal qiladi: debug ichidagi import "ms" avval debug/node_modules ga qaraydi va 2.1.3 ni topadi. Bizning kodimiz esa ildizdagi 2.0.0 ni oladi. Ikkalasi baxtli — lekin diskda ikki nusxa.
3.3 Dublikatlar: muqarrar va keraksiz
Ba'zi takrorlar muqarrar. Express 4.22.3 ni o'rnatsak:
npm ls msdublikat@1.0.0 …\kurs\mashqlar\16\10-node-modules\dublikat
`-- express@4.22.3
+-- debug@2.6.9
| `-- ms@2.0.0
`-- send@0.19.2
`-- ms@2.1.3
debug@2.6.9 aynan ms@2.0.0 ni, send esa 2.1.3 ni talab qiladi. Bitta versiya ikkalasini qondira olmaydi. npm find-dupes ("takrorlarni top") bu yerda hech narsa taklif qilmaydi.
Keraksiz takror esa bunday paydo bo'ladi. dedupe/ da avval debug@4.4.3 (u ms@2.1.3 ni olib keldi), keyin npm i ms@2.1.2 — package.json ga "^2.1.2" yozildi:
npm ls msdedupe@1.0.0 …\kurs\mashqlar\16\10-node-modules\dedupe
+-- debug@4.4.3
| `-- ms@2.1.3
`-- ms@2.1.2
Ikki nusxa — lekin 2.1.3 bizning ^2.1.2 ga ham mos! npm ularni o'zi birlashtirmadi: o'rnatish paytida faqat so'ralgan narsani qo'ydi.
npm find-dupeschange ms 2.1.2 => 2.1.3
remove ms 2.1.3
removed 1 package, and changed 1 package in 485msfind-dupes — "quruq mashq": nima qilishini aytadi, diskka tegmaydi. Haqiqatan bajarish — npm dedupe:
npm dedupe
npm ls ms
removed 1 package, changed 1 package, and audited 3 packages in 1s
found 0 vulnerabilities
dedupe@1.0.0 …\kurs\mashqlar\16\10-node-modules\dedupe
+-- debug@4.4.3
| `-- ms@2.1.3 deduped
`-- ms@2.1.3
Bitta nusxa, deduped. Katta loyihalarda npm dedupe lock-faylni sezilarli kichraytirishi mumkin. Lekin u versiyalarni o'zgartiradi — keyin testlarni yuriting.
Tekshirib ko'ring: Express misolida
msning ikki nusxasi bor. Bu muammomi?
Javob
Odatda yo'q: ms — holatsiz kichik funksiya, ikki nusxa faqat bir necha KB disk. Muammo nusxa holat saqlaganda boshlanadi — masalan, React. Ikki nusxa bir-birining ichki ma'lumotini ko'rmaydi («Ikki nusxa React» bo'limi).
4. Fantom bog'liqlik
4.1 Nima u
Hoisting'ning yon ta'siri: ildizdagi node_modules da siz so'ramagan paketlar ham turadi. Node esa package.json ga qaramaydi — u faqat papkani qidiradi. Natijada siz e'lon qilinmagan paketni import qila olasiz. Bu phantom dependency (fantom bog'liqlik) — "arvoh": bor, lekin hujjatda yo'q. «Nega bu kerak?» bo'limidagi ms aynan shunday: uni eslint → debug olib kelgan.
4.2 Qachon portlaydi
fantom/ da faqat npm i -D -E eslint@10.12.0. Kod esa debug ni ishlatadi:
// log.js — debug paketini package.json ga yozmasdan ishlatadi
import createDebug from "debug";
const log = createDebug("bahor:kassa");
log.enabled = true;
log("buyurtma qabul qilindi");node log.js2026-10-10T15:04:45.819Z bahor:kassa buyurtma qabul qilindiIshlaydi (terminalda vaqt o'rniga rangli +0ms chiqadi). npm ls debug sababni ko'rsatadi:
fantom@1.0.0 …\kurs\mashqlar\16\10-node-modules\fantom
`-- eslint@10.12.0
+-- @eslint/config-array@0.23.5
| `-- debug@4.4.3 deduped
`-- debug@4.4.3
Serverda esa (bog'liqlik turlari darsidagi --omit=dev):
npm ci --omit=dev
node log.jsError [ERR_MODULE_NOT_FOUND]: Cannot find package 'debug' imported from …\kurs\mashqlar\16\10-node-modules\fantom\log.jsESLint o'rnatilmadi — u bilan birga "arvoh" ham ketdi. Fantom bog'liqlik yana uch holatda portlaydi: ESLint yangi versiyada debug dan voz kechsa; debug ning boshqa MAJOR versiyasini olib kelsa; yoki loyiha pnpm'ga o'tsa — pnpm fantomlarni umuman ko'rsatmaydi (pnpm).
Davosi: ishlatayotgan har paketni o'zingiz e'lon qiling — npm i -P -E debug@4.4.3. Topish uchun: bog'liqlik turlari darsidagi tekshiruvchi skript, ESLint qoidalari va knip (knip darsi).
5. ERESOLVE: peer to'qnashuvi
5.1 Xabarni o'qish
Bog'liqlik turlari darsidagi xato — TypeScript 7.0.2 o'rnatilgan loyihaga typescript-eslint@8.71.1:
npm error code ERESOLVE
npm error ERESOLVE unable to resolve dependency tree
npm error
npm error While resolving: t10a@1.0.0
npm error Found: typescript@7.0.2
npm error node_modules/typescript
npm error dev typescript@"7.0.2" from the root project
npm error
npm error Could not resolve dependency:
npm error peer typescript@">=4.8.4 <6.1.0" from typescript-eslint@8.71.1
npm error node_modules/typescript-eslint
npm error dev typescript-eslint@"8.71.1" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry this command with --force or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution.
npm error
npm error
npm error For a full report see:
npm error …\npm-cache\_logs\2026-10-07T06_40_49_672Z-eresolve-report.txtUch qismga bo'lib o'qiymiz:
| Qism | Qatorlar | Ma'nosi |
|---|---|---|
While resolving |
t10a@1.0.0 |
kimning daraxtini qurayotgandim |
Found |
typescript@7.0.2 … from the root project |
daraxtda nima bor va kim so'ragan |
Could not resolve |
peer typescript@">=4.8.4 <6.1.0" |
qaysi talab bajarilmadi |
Oxirgi gap — tavsiya: "Yuqoridagi to'qnashuvni tuzating yoki --force yoki --legacy-peer-deps bilan qayta urining". Bayroqlar nima uchun? "Noto'g'ri (va ehtimol buzilgan) daraxtni qabul qilish uchun". npm o'zi ogohlantirmoqda: bu bayroqlar muammoni hal qilmaydi, faqat ko'zni yumadi. eresolve-report.txt — to'liq hisobot fayli.
5.2 --legacy-peer-deps ning narxi
Baribir sinab ko'ramiz. peer/ da TypeScript 7.0.2 va ESLint 10.12.0 bor:
npm i -D -E typescript-eslint@8.71.1 --legacy-peer-deps
added 17 packages, and audited 97 packages in 2m
29 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilitiesO'rnatildi. --legacy-peer-deps — "npm 6 dagidek: peer talablariga e'tibor berma". Lekin npm ls typescript haqiqatni aytadi: npm error invalid: typescript@7.0.2 …. Oddiy eslint.config.js (recommendedTypeChecked) bilan bitta .ts faylni tekshiramiz:
npx eslint narx.tstypescript-eslint does not support TS 7.0.
Please see https://devblogs.microsoft.com/typescript/announcing-typescript-7-0/#running-side-by-side-with-typescript-6.0 to run typescript-eslint using the TS 6 API.
See also https://github.com/typescript-eslint/typescript-eslint/issues/10940 for tracking typescript-eslint's support for TS >=7.1
Oops! Something went wrong! :(
ESLint: 10.12.0
Error: typescript-eslint does not support TS 7.0.
…"typescript-eslint TS 7.0 ni qo'llamaydi. TypeScript 6 API bilan yonma-yon ishlatish uchun — havola". Peer talabi bejiz yozilmagan edi: plagin TypeScript'ning ichki API'siga tayanadi, TS 7 da esa u yo'q. ERESOLVE o'rnatishda, ya'ni eng arzon joyda ogohlantirgan edi. Bayroq xatoni ishlayotgan asbobga ko'chirdi.
--force ham shunga o'xshaydi, faqat yanada qo'pol: u to'qnashuvda ham, boshqa himoyalarda ham to'xtamaydi. --strict-peer-deps esa aksincha — hatto ogohlantirishni ham xatoga aylantiradi.
5.3 To'g'ri yechimlar
- Mos versiyalarni tanlang.
npm view typescript-eslint peerDependencies— qaysi TypeScript kerak. Bizda:<6.1.0. - Ikkala versiyani yonma-yon saqlang. Xabardagi havola aynan shuni taklif qiladi.
vazifalar15-qismdan beri shunday:@typescript/native— TS 7 (tscuchun),typescript— TS 6 (ESLint uchun), taxallus bilan (npm:). - Plagin yangilanishini kuting yoki uning issue'sini kuzating.
- Vaqtincha va ongli ravishda —
overrides. Hech qachon "jim bo'lsin" uchun--legacy-peer-depsni.npmrcga yozmang: u barcha kelajakdagi to'qnashuvlarni ham yashiradi.
flowchart LR
E["ERESOLVE"] --> V["npm view … peerDependencies"]
V --> M{"mos versiya bormi?"}
M -- "ha" --> U["o'sha versiyani o'rnating"]
M -- "yo'q" --> Y["yonma-yon (taxallus)<br/>yoki kuting"]
E -. "--legacy-peer-deps" .-> X["o'rnatildi, lekin<br/>ishlaganda buziladi"]Tekshirib ko'ring: Hamkasbingiz README'ga yozibdi: "O'rnatish:
npm install --legacy-peer-deps". Bu loyiha haqida nima deydi?
Javob
Loyihada hal qilinmagan peer to'qnashuvi bor: qaysidir plagin o'zi qo'llamaydigan versiya bilan ishlayapti. Ehtimol hozircha ishlaydi, lekin kafolat yo'q. npm ls dagi invalid qatorlarini toping va to'qnashuvni yeching — shunda bayroq ham kerak bo'lmaydi.
6. Ikki nusxa React
Fantomdan ham xavfliroq holat — holatli paketning ikki nusxasi. Klassik misol — React (17-qismda o'rganamiz; hozir bilish shart emas: u interfeys qismlarini — "komponentlar"ni — chizadigan kutubxona). React o'z ichida "hozir qaysi komponent chizilyapti" degan yagona holatni saqlaydi.
Sardor «Bahor» tugmasini alohida bahor-ui paketiga chiqardi. Paketni sinash uchun uning ichiga ham React o'rnatdi (devDependencies). Saytda esa npm i ../bahor-ui — paket papkadan, kirish nuqtalari darsidagidek havola bilan ulandi.
// tugma.js — «Bahor» tugmasi: necha marta bosilganini eslaydi
import { createElement, useState } from "react";
export function OrderButton() {
const [count] = useState(0);
return createElement("button", null, `Buyurtma (${count})`);
}Sayt tugmani HTML qatoriga aylantiradi (React 19.3.0, react-dom/server):
node render.jsInvalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.
…\ikki-react\bahor-ui\node_modules\react\cjs\react.development.js:1309
return resolveDispatcher().useState(initialState);
^
TypeError: Cannot read properties of null (reading 'useState')Xabarning uchinchi sababi — bizniki: "ilovada React'ning bir nechta nusxasi bo'lishi mumkin". Yo'lga qarang: bahor-ui\node_modules\react — sayt React'ni emas, paket ichidagi nusxani ishlatdi. Node qidiruvi tugma.js turgan joydan boshlandi va birinchi node_modules/react ni topdi. react-dom esa saytning React'iga ulangan. Ikki nusxa — ikki xil "joriy komponent" holati.
Birinchi qadam — bog'liqlik turlari darsidagi qoida: bahor-ui React'ni peerDependencies da e'lon qiladi (bizda shunday). Lekin bu yetmadi. Sinov uchun bahor-ui/node_modules ni olib qo'ydik — endi Cannot find package 'react' imported from …\bahor-ui\tugma.js (ERR_MODULE_NOT_FOUND). Nega? file: havola (symlink) bo'lgani uchun Node tugma.js ning haqiqiy joyidan qidiradi — bahor-ui papkasi saytning yonida turibdi, ichida emas.
Ishlaydigan yechim — paketni havola emas, nusxa qilib o'rnatish:
npm i ../bahor-ui --install-links
node render.js
changed 1 package, and audited 5 packages in 2s
found 0 vulnerabilities
<button>Buyurtma (0)</button>--install-links — "file: paketni arxivga yig'ib, nusxa sifatida qo'y" (xuddi registrdan kelgandek; node_modules arxivga tushmaydi). Endi bahor-ui sayt ichida, uning import "react" i saytning yagona React'ini topdi. Monorepo va npm link bilan ishlaganda bu muammo ayniqsa ko'p chiqadi (Begona paketni tuzatish); bundler'larda buning uchun alohida sozlama bor (Vite'da resolve.dedupe).
7. Ko'p uchraydigan xatolar
| Xabar / belgi | Sabab | Davosi |
|---|---|---|
ERESOLVE unable to resolve dependency tree |
peer diapazoniga mos emas | mos versiya yoki yonma-yon |
invalid: "…" from … (npm ls) |
--legacy-peer-deps yoki override |
to'qnashuvni yeching |
Invalid hook call |
React'ning ikki nusxasi | peer + ichki nusxani o'chirish |
ERR_MODULE_NOT_FOUND faqat serverda |
fantom bog'liqlik | paketni e'lon qiling |
| Xabar / belgi | Sabab | Davosi |
|---|---|---|
| e'lon qilinmagan paket ishlayapti | hoisting yoki ota papka | npm ls nom, require.resolve |
| bir paketning ikki nusxasi | diapazonlar kesishmaydi yoki takror | npm find-dupes, npm dedupe |
typescript-eslint does not support TS 7.0 |
peer talabi chetlab o'tilgan | TS 6 API'ni yonma-yon |
8. Mashqlar
Mashqlar kurs/mashqlar/16/10-node-modules/ da.
1-mashq (oson): Daraxtni o'qing
«Dublikatlar» bo'limidagi Express daraxtiga qarab javob bering:
sendqaysimsni ishlatadi?debug@2.6.9qaysimsni ishlatadi?- Ildizdagi
node_modules/msqaysi versiya bo'lishi mumkin?npm ls ms --parseablebilan tekshiring.
Yechim
--parseable daraxt o'rniga diskdagi yo'llarni beradi. Bizda Express 4.22.3 da ildizda ms@2.0.0, send/node_modules/ms da esa 2.1.3 turibdi — npm ko'proq so'ralgan versiyani ko'taradi. Sizda (boshqa Express versiyasida) tartib boshqacha bo'lishi mumkin — qoida bir xil: har paket o'ziga eng yaqin node_modules dagi nusxani oladi.
2-mashq (o'rta): Arvohni tuting
fantom/ da (eslint faqat dev'da, log.js darsdagidek):
npm ci --omit=devvanode log.js. Xato:- Bitta buyruq bilan tuzating va 1-qadamni takrorlang.
Yechim
npm i -P -E debug@4.4.3. Endi package.json:
{
"dependencies": {
"debug": "4.4.3"
},
"devDependencies": {
"eslint": "10.12.0"
}
}npm ci --omit=dev, node log.js:
2026-10-10T15:04:45.819Z bahor:kassa buyurtma qabul qilindiVaqt sizda boshqacha. Endi debug ESLint'ga bog'liq emas.
3-mashq (o'rta): Takrorni yo'qoting
dedupe/ papkasida darsdagi holatni yarating (debug@4.4.3, keyin ms@2.1.2). npm find-dupes nima taklif qiladi? npm dedupe dan keyin npm ls ms da qaysi so'z paydo bo'ladi:
Yechim
find-dupes: change ms 2.1.2 => 2.1.3, remove ms 2.1.3. npm dedupe — removed 1 package, changed 1 package. Keyin npm ls ms: ms@2.1.3 deduped va ildizda ms@2.1.3. package.json o'zgarmadi ("^2.1.2") — 2.1.3 bu diapazonga mos, faqat lock va disk o'zgardi.
4-mashq (qiyin): Node qidiruvini takrorlang
qidiruv/yollar.mjs da lookupPaths(dir) yozing — dir papkasidan disk ildizigacha node_modules yo'llari ro'yxati, Node bilan bir xil tartibda. Nomi node_modules bo'lgan papkaga yana node_modules qo'shilmaydi. yollar.test.mjs da natijani Node'ning o'zi bilan solishtiring: createRequire(fayl).resolve.paths("ms").
Ishoralar: path.dirname — ota papka; disk ildizida path.dirname(x) === x. path.basename — oxirgi qism. createRequire — ESM fayldan require yaratadi (CommonJS va ESM).
Yechim
yollar.mjs:
// yollar.mjs — Node paketni qaysi node_modules larda qidiradi?
import path from "node:path";
// dir — import yozilgan fayl turgan papka (absolyut yo'l)
export function lookupPaths(dir) {
const result = [];
let current = path.resolve(dir);
while (true) {
// node_modules ichida yana node_modules/node_modules qidirilmaydi
if (path.basename(current) !== "node_modules") {
result.push(path.join(current, "node_modules"));
}
const parent = path.dirname(current);
if (parent === current) break; // disk ildiziga yetdik
current = parent;
}
return result;
}yollar.test.mjs:
// yollar.test.mjs — natijani Node'ning o'zi bilan solishtiradi
import { test } from "node:test";
import assert from "node:assert/strict";
import { createRequire } from "node:module";
import path from "node:path";
import { lookupPaths } from "./yollar.mjs";
// Node ro'yxati oxiriga global papkalarni (~/.node_modules)
// qo'shadi — ularni solishtirmaymiz
function nodePaths(dir) {
const req = createRequire(path.join(dir, "fayl.js"));
const all = req.resolve.paths("ms");
return all.slice(0, lookupPaths(dir).length);
}
test("Node bilan bir xil tartib", () => {
const dirs = [
process.cwd(),
path.join(process.cwd(), "src", "hisob"),
path.join(process.cwd(), "node_modules", "debug", "src"),
];
for (const dir of dirs) {
assert.deepEqual(lookupPaths(dir), nodePaths(dir), dir);
}
});
test("birinchi — eng yaqin papka, oxirgi — disk ildizi", () => {
const list = lookupPaths(path.join(process.cwd(), "src"));
const src = path.join(process.cwd(), "src");
assert.equal(list[0], path.join(src, "node_modules"));
assert.equal(path.dirname(list.at(-1)), path.parse(list[0]).root);
});ℹ tests 2
ℹ pass 2
ℹ fail 0Uchinchi papka (node_modules/debug/src) — node_modules ni o'tkazib yuborish qoidasining sinovi: Node …/node_modules/node_modules ni qidirmaydi. Testlar papkalar mavjud bo'lmasa ham ishlaydi — Node ham, bizning funksiya ham faqat yo'l bilan hisoblaydi.
9. Real ishda
- "Menda ishlaydi" xatolarining katta qismi — fantom bog'liqlik yoki ota papkadagi
node_modules. Birinchi savol: "npm ls <nom>nima deydi?". ERESOLVE— yangi plagin o'rnatishda eng ko'p uchraydigan xato. Professional javob:npm view … peerDependencies, keyin qaror.--legacy-peer-deps— oxirgi chora, sababi yozilgan holda.- Ikki nusxa React/Vue — monorepo va
npm linkdagi klassik muammo; bundler'lardaresolve.dedupesozlamasi aynan shuning uchun bor (Vite darslarida). - Intervyu: "hoisting nima?", "phantom dependency qanday paydo bo'ladi?", "
--legacy-peer-depsnima qiladi va nega xavfli?".
Xulosa
- Node paketni joriy papkadan disk ildizigacha har
node_modulesda qidiradi; birinchi topilgani ishlatiladi — loyihadan tashqaridagisi ham. - npm paketlarni ildizga ko'taradi (hoisting); mos kelmagan versiya ichma-ich joylashadi;
deduped— takror qo'yilmagan. npm find-dupes— keraksiz takrorlarni ko'rsatadi,npm dedupe— tuzatadi; kesishmaydigan diapazonlarda takror muqarrar.- Fantom bog'liqlik — e'lon qilinmagan, lekin hoisting tufayli ishlayotgan paket;
--omit=dev, yangilanish yoki pnpm'da portlaydi. ERESOLVE:Found— bor narsa,Could not resolve— bajarilmagan peer talabi.--legacy-peer-depsxatoni o'rnatishdan ishlayotgan asbobga ko'chiradi.- Holatli kutubxonaning (React) ikki nusxasi —
Invalid hook call; yechim — peer va bitta nusxa.
Keyingi dars: npx, npm create va bir martalik CLI'lar — paketni o'rnatmasdan ishga tushirish, npm create vite@latest va @latest ning xavfi.
Manbalar
- Node.js Docs (v24): Modules: Loading from node_modules folders, ESM: Resolution algorithm
- npm Docs (v11): npm dedupe, npm find-dupes, config — legacy-peer-deps, strict-peer-deps
- React: Rules of Hooks — Invalid Hook Call Warning
- typescript-eslint issue #10940 — TypeScript 7 qo'llovi
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!