IlmHamroh
JavaScript Full-stack/16-qism. Frontend asboblari: npm, bundlerlar, config18/48-dars18 daqiqa
Mundarija (29)

Begona paketni tuzatish: patch-package, overrides va npm link

Qisqacha: Kutubxonada xato topdingiz, tuzatilgan versiya esa hali yo'q. node_modules dagi faylni qo'lda o'zgartirish keyingi npm ci da yo'qoladi. To'g'ri yo'llar: patch-package (yoki pnpm patch) o'zgarishni patches/ papkasiga diff sifatida saqlab, har o'rnatishda qayta qo'llaydi; overrides chuqurdagi (tranzitiv) paketning versiyasini majburlaydi; npm link, file: va yalc o'zingiz tuzatayotgan kutubxonani loyihada sinashga imkon beradi. Har vaqtinchalik yamoq bilan birga — kutubxona muallifiga issue yoki PR.

Bu darsda

  • patch-package bilan yamoq yasaysiz va uni jamoaga git orqali yetkazasiz.
  • Yamoq versiya o'zgarganda nima bo'lishini (ogohlantirish va xato) bilasiz.
  • overrides bilan tranzitiv paket versiyasini almashtirasiz va EOVERRIDE xatosini tushunasiz.
  • npm link, file: va yalc farqini bilasiz.
  • Tuzatishni kutubxona muallifiga (upstream) qanday yuborishni bilasiz.

Oldin bilishingiz kerak: node_modules ichida: modul qidirish va peer xatolari, Ta'minot zanjiri xavfsizligi, Bog'liqliklarni yangilash strategiyasi.

1. Nega bu kerak?

Oldingi darsda yangilashni o'rgandik. Lekin ba'zan yangilash yordam bermaydi: xato eng yangi versiyada ham bor.

Sardor «Bahor» menyusi uchun har taomga chiroyli manzil yasayapti: "Lag'mon" → /menyu/lagmon. Buning uchun mashhur slugify kutubxonasini (1.6.9, 2026-10 holatiga eng yangisi) oldi. Natija:

text
/menyu/lag'mon
/menyu/ko'k-choy
/menyu/ozbek-palovi

Uch taom — uch xil xulq. Taom nomlari bazaga turli manbalardan kelgan: biri ‘ (U+2018, "chap qo'shtirnoq"), biri ʻ (U+02BB, o'zbek lotin alifbosining rasmiy "o'"si) bilan. slugify birinchisini oddiy ' ga aylantiradi va URL'da apostrof qoladi. Ikkinchisini esa jimgina o'chiradi. Sardorga bir xil natija kerak: belgilar umuman bo'lmasin.

Variantlar:

  1. Kutubxona API'si — slugify da strict: true bor, u harf-raqamdan boshqa hamma belgini o'chiradi. Ko'pincha shu yetadi va birinchi navbatda shuni izlang.
  2. Muallifga xabar berish — issue va PR. Lekin tuzatish qachon chiqishi noma'lum.
  3. Vaqtinchalik yamoq — node_modules dagi kodni o'zgartirib, o'zgarishni saqlab qo'yish.

Bu dars — uchinchi yo'l haqida, va ikkinchisi bilan birga. Mexanizmni ko'rish uchun slugify ning belgilar xaritasini o'zgartiramiz: kichik, xavfsiz va natijasi darhol ko'rinadi.

Hayotiy o'xshatish: oshxonaga kelgan pichoqning dastasi bo'shab qoldi. Zavodga xat yozasiz (issue). Lekin xat javobini kutib, ish to'xtamaydi — dastani vaqtincha mahkamlaysiz va boshqa oshpazlar ham buni bilishi uchun yozib qo'yasiz (yamoq).

Maslahat: Chiqishlar 2026-10-10 da Windows 11, Node 24.21.0, npm 11.19.0, patch-package 8.0.1 va pnpm 12.10.1 bilan sinov papkalarida olingan. Uzun yo'llar … bilan qisqartirildi.

2. Nega node_modules ni shunchaki tahrirlab bo'lmaydi

node_modules/slugify/slugify.js ni ochib, o'zgartirsangiz — sizda ishlaydi. Lekin Lock-fayllar va npm ci darsidan bilasiz: node_modules git'da yo'q va npm ci uni har safar o'chirib, registrdan qayta quradi. Jamoadoshingizda, CI'da va ertaga o'zingizda o'zgarish yo'q.

Kerak bo'lgani — o'zgarishning o'zini (diff'ni) git'da saqlash va har o'rnatishdan keyin uni avtomatik qayta qo'llash. Buni patch-package qiladi.

flowchart TB
  A["node_modules dagi<br/>faylni tahrirlash"] --> B["npx patch-package slugify"]
  B --> C["patches/slugify+1.6.9.patch<br/>(git'ga)"]
  C --> D["npm ci: toza<br/>slugify o'rnatiladi"]
  D --> E["postinstall: patch-package<br/>yamoqni qo'llaydi"]

Diagrammaning o'rtasiga qarang: git'ga paket emas, faqat .patch fayl kiradi — o'zgargan qatorlar ro'yxati.

3. patch-package

3.1 Yamoq yasash

Yamoq (patch) — ikki fayl orasidagi farqni yozib qo'ygan matn: qaysi qator o'chdi (-), qaysi qo'shildi (+). Uni Git'dagi git diff chiqishidan bilasiz — format o'sha.

Avval o'rnatamiz:

bash
npm i -D -E patch-package@8.0.1

Keyin node_modules/slugify/slugify.js da belgilar xaritasidagi "‘":"\'","’":"\'" qismini "‘":"","’":"","ʻ":"","ʼ":"" ga almashtiramiz: to'rt xil apostrof ham bo'sh satrga aylansin. Natija darhol o'zgardi:

text
/menyu/lagmon
/menyu/kok-choy
/menyu/ozbek-palovi

Endi o'zgarishni yozib olamiz:

bash
npx patch-package slugify
text
patch-package 8.0.1
• Creating temporary folder
• Installing slugify@1.6.9 with npm
• Diffing your files with clean files
✔ Created file patches/slugify+1.6.9.patch

💡 slugify is on GitHub! To draft an issue based on your patch run

    npx patch-package slugify --create-issue

Qadamlar tarjimasi: "vaqtinchalik papka yaratildi → unga slugify@1.6.9 ning toza nusxasi o'rnatildi → sizning fayllaringiz toza nusxa bilan solishtirildi → yamoq fayli yaratildi". Oxirida maslahat: "slugify GitHub'da — yamoq asosida issue qoralamasini yasash uchun --create-issue". Bu ikkinchi yo'lga ko'prik, unga keyinroq qaytamiz.

Fayl nomida versiya bor — slugify+1.6.9.patch. Bu muhim, pastda ko'ramiz. Fayl boshi:

text
diff --git a/node_modules/slugify/slugify.js b/node_modules/slugify/slugify.js
index f5a6a1e..fc9ac2b 100644
--- a/node_modules/slugify/slugify.js
+++ b/node_modules/slugify/slugify.js
@@ -12,7 +12,7 @@
     root[name] = factory()
   }
 }('slugify', this, function () {
-  var charMap = JSON.parse('{"$":"dollar","%":"percent", …
+  var charMap = JSON.parse('{"$":"dollar","%":"percent", …

- va + qatorlari juda uzun — biz … bilan kesdik. slugify da butun belgilar xaritasi bitta qatorda, shuning uchun to'rt belgilik o'zgarish uchun yamoq 14 208 baytli bo'ldi. Kichik kutubxonalarda shunday bo'ladi: yamoq qatorlar bo'yicha ishlaydi.

3.2 Har o'rnatishda qo'llash

Yamoq o'z-o'zidan qo'llanmaydi. Loyihaning package.json iga scripts darsidagi postinstall qo'shiladi:

bash
npm pkg set scripts.postinstall="patch-package"

Endi node_modules ni o'chirib, toza o'rnatamiz. Chiqishda ikki narsaga qarang: Applying patches... ostidagi qator va oxiridagi zaiflik xabari:

bash
npm ci
text
> menyu@1.0.0 postinstall
> patch-package

patch-package 8.0.1
Applying patches...
slugify@1.6.9 ✔

added 57 packages, and audited 58 packages in 11s

4 high severity vulnerabilities

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

slugify@1.6.9 ✔ — yamoq qo'llandi, node slug.js yana /menyu/lagmon beradi. Git'ga patches/ papkasi, package.json va lock qo'shiladi. Jamoadoshingiz npm ci qilsa, hammasi o'zi bo'ladi.

Ta'minot zanjiri darsidagi allowScripts bu yerga tegmaydi: u faqat bog'liqliklarning skriptlariga tegishli. Loyihaning o'z postinstall i — sizning kodingiz, u doim ishlaydi.

3.3 Tuzoq: 4 high severity vulnerabilities

Yuqoridagi chiqishning oxiriga qarang. patch-package 8.0.1 o'zi bilan 56 ta paket olib keldi, ulardan biri — braces:

text
braces  *
Severity: high
braces vulnerable to stack-exhaustion denial of service through deeply nested patterns - https://github.com/advisories/GHSA-vfj7-8cjw-p6xm
fix available via `npm audit fix --force`
Will install patch-package@6.0.7, which is a breaking change

braces * — hamma versiya zaif, tuzatish yo'q. npm'ning "tuzatishi" — patch-package'ni 6.0.7 ga, ya'ni ancha eski versiyaga tushirish. Ta'minot zanjiri darsidagi qoida shu yerda ishlaydi: --force dan oldin Will install … ni o'qing. Bu yerda u ma'nosiz.

Xavfni baholaymiz: zaiflik — "juda chuqur ichma-ich naqsh berilsa, dastur osilib qoladi". patch-package faqat sizning kompyuteringizda va CI'da, sizning naqshlaringiz bilan ishlaydi. Brauzerga hech narsa bormaydi: npm audit --omit=dev — found 0 vulnerabilities. Xulosa: bu dasturchi asbobidagi past real xavf. Uni bilib qabul qilamiz va Paket tanlash darsidagi savolni ham beramiz: "bir yamoq uchun 56 paket — narxi oqlanadimi?". Yamoq ko'p bo'lsa — ha. Bitta va qisqa muddatli bo'lsa — pastdagi pnpm patch yoki API yo'li arzonroq.

Tekshirib ko'ring: Sardor yamoq yasadi, lekin postinstall ni qo'shishni unutdi va patches/ ni commit qildi. Jamoadoshida nima bo'ladi?

Javob

Hech narsa — va bu eng yomoni. npm ci toza slugify ni o'rnatadi, yamoq fayli diskda turadi, lekin uni hech kim qo'llamaydi. Xato bo'lmaydi, faqat jamoadoshida /menyu/lag'mon qaytadi. Shuning uchun yamoq va postinstall doim bitta commit'da bo'ladi va yamoq qo'llanganini tekshiradigan test yoziladi.

4. Versiya o'zgarganda

4.1 Ogohlantirish

Yamoq aniq versiya uchun yasalgan. slugify boshqa versiyaga o'tsa-chi? Sinab ko'ramiz — 1.6.8 o'rnatib, yamoqni qo'llaymiz:

bash
npx patch-package
text
patch-package 8.0.1
Applying patches...
slugify@1.6.9 ✔

Warning: patch-package detected a patch file version mismatch

  Don't worry! This is probably fine. The patch was still applied
  successfully. Here's the deets:

  Patch file created for

    slugify@1.6.9

  applied to

    slugify@1.6.8
…
---
patch-package finished with 1 warning(s).

"Xavotir olmang, ehtimol hammasi joyida: yamoq baribir muvaffaqiyatli qo'llandi. U 1.6.9 uchun yasalgan, 1.6.8 ga qo'llandi". O'rtadagi maslahat qatorlarini … bilan qisqartirdik. Ulardan biri qiziq: "paket kutilgandek ishlashiga ishonch hosil qiling (testlar yozgansiz, to'g'rimi?)".

4.2 Xato

Kod ancha farq qilsa, yamoq qo'llanmaydi. 1.5.0 da:

bash
npx patch-package
text
patch-package 8.0.1
Applying patches...

**ERROR** Failed to apply patch for package slugify at path
  
    node_modules/slugify

  This error was caused because slugify has changed since you
  made the patch file for it. This introduced conflicts with your patch,
  just like a merge conflict in Git when separate incompatible changes are
  made to the same piece of code.

  Maybe this means your patch file is no longer necessary, in which case
  hooray! Just delete it!
…

"Yamoq qo'llanmadi: siz yamoq yasagandan beri slugify o'zgargan. Bu Git'dagi merge conflict kabi. Balki yamoq endi kerak emasdir — unda o'chiring, hurray!".

Eng xavflisi — chiqish kodi. Bu chiqishdan keyin echo $? — 0. Ya'ni lokal kompyuterda yamoq qo'llanmasa ham, o'rnatish "muvaffaqiyatli" tugaydi. npx patch-package --error-on-fail bilan esa — 1. Hujjatga ko'ra CI muhitida (CI o'zgaruvchisi bor joyda) bu sukut bo'yicha yoqiq. Lekin lokal xatoni o'tkazib yubormaslik uchun loyiha testi kerak — masalan, slugify("Lag‘mon") ning natijasini tekshiradigan bitta test.

Diqqat: Yamoq — texnik qarz. Har yamoq uchun yozib qo'ying: nega kerak, upstream'dagi issue havolasi, qachon olib tashlanadi. vazifalar dagi TEXNIK-QARZ.md kabi faylga. Kutubxona tuzatilgan versiyasini chiqargach — yangilang va yamoqni o'chiring.

4.3 pnpm patch

pnpm'da bu imkoniyat o'rnatilgan, qo'shimcha paket kerak emas:

bash
npx pnpm@12.10.1 patch slugify@1.6.9
text
Patch: You can now edit the package at:

  …\node_modules\.pnpm_patches\slugify@1.6.9

To commit your changes, run:

  pnpm patch-commit "…\node_modules\.pnpm_patches\slugify@1.6.9"

pnpm paketning tahrirlanadigan nusxasini alohida papkaga chiqaradi. O'zgartirasiz, keyin pnpm patch-commit <papka>. Natijada patches/slugify@1.6.9.patch yaratiladi va pnpm-workspace.yaml ga yoziladi:

text
patchedDependencies:
  slugify@1.6.9: patches/slugify@1.6.9.patch

postinstall kerak emas — pnpm yamoqni o'rnatishning bir qismi sifatida qo'llaydi. Yamoq qo'llanmasa — o'rnatish xato bilan to'xtaydi. Bun'da ham shunday: bun patch.

5. overrides: chuqurdagi versiyani almashtirish

5.1 Muammo

Yamoq kodni o'zgartiradi. Ba'zan esa kod emas, versiya muammo: chuqurdagi paketning tuzatilgan versiyasi bor, lekin uni olib keladigan paket hali yangilanmagan. Ta'minot zanjiri darsidagi holat: vite → postcss → source-map-js 1.2.1 (zaif).

source-map-js ni siz o'rnatmagansiz — u tranzitiv bog'liqlik (node_modules ichida darsidagi atama): bog'liqlikning bog'liqligi. Uning versiyasini postcss tanlaydi.

5.2 overrides maydoni

package.json dagi overrides — "daraxtning qayerida bo'lmasin, bu paket uchun shu versiyani ishlat" degan buyruq. Sinov loyihasini 2026-09-29 holatiga qaytardik (npm i --before=2026-09-29):

bash
npm ls source-map-js
text
ovr@1.0.0 …\ovr
`-- vite@8.3.1
  `-- postcss@8.5.28
    `-- source-map-js@1.2.1

overrides qo'shamiz:

bash
npm pkg set overrides.source-map-js=1.2.2
npm install
text
changed 1 package, and audited 16 packages in 1s

found 0 vulnerabilities
bash
npm ls source-map-js
text
ovr@1.0.0 …\ovr
`-- vite@8.3.1
  `-- postcss@8.5.28
    `-- source-map-js@1.2.2 overridden

overridden — "majburan almashtirilgan". package.json da:

json
{
  "devDependencies": {
    "vite": "8.3.1"
  },
  "overrides": {
    "source-map-js": "1.2.2"
  }
}

Halol bo'laylik: bu holatda npm audit fix ham yetardi, chunki postcss ning ^1.2.1 chegarasi 1.2.2 ni qabul qiladi. overrides ning haqiqiy kuchi — chegaradan tashqari versiyani majburlash. Masalan, kutubxona "lodash": "^3" deb so'raydi, siz esa 4 ni bermoqchisiz. Bu xavfli: kutubxona 4 bilan ishlashiga hech kim kafolat bermaydi — testlar shart.

5.3 Shakllar va EOVERRIDE

Shakl Ma'nosi
"source-map-js": "1.2.2" hamma joyda
"postcss": { "nanoid": "3.3.20" } faqat postcss ichida
"vite@8.3.1": { … } faqat vite'ning shu versiyasi ichida
"nanoid": "$nanoid" to'g'ridan-to'g'ri bog'liqlikdagi versiya bilan bir xil

Oxirgi shakl tuzoqdan himoya qiladi. Loyihada nanoid 3.3.20 ham to'g'ridan-to'g'ri bor, overrides da esa 3.3.11 yozilsa:

bash
npm install
text
npm error code EOVERRIDE
npm error Override for nanoid@3.3.20 conflicts with direct dependency
npm error A complete log of this run can be found in: …

"nanoid@3.3.20 uchun override to'g'ridan-to'g'ri bog'liqlik bilan ziddiyatda". npm ikki xil talabni qabul qilmaydi. "nanoid": "$nanoid" — "o'zim dependencies da yozgan versiyani hamma joyga ber" — ziddiyat yo'q, npm ls nanoid da postcss ostida nanoid@3.3.20 deduped.

Boshqa menejerlarda: Yarn — resolutions maydoni, pnpm — pnpm-workspace.yaml dagi overrides. G'oya bir xil.

Tekshirib ko'ring: Malika overrides ga "react": "19.3.0" yozdi va xato yo'qoldi. Bobur: "overrides — ogohlantirishni o'chirish tugmasi emas" dedi. Kim haq va nega?

Javob

Bobur. overrides npm'ning tekshiruvini (masalan, peer xatosi ERESOLVE) chetlab o'tadi, lekin kutubxonani yangi versiyaga moslamaydi. Agar kutubxona boshqa React bilan sinalmagan bo'lsa, xato endi o'rnatishda emas, ishlash paytida chiqadi. overrides — o'ylangan qaror: sabab, test va upstream issue bilan.

6. O'z kutubxonangizni loyihada sinash

6.1 Vaziyat

Endi teskari holat. Sardor o'zi kichik kutubxona yozmoqda — bahor-narx (narxni chiroyli yozadi), va uni kassa loyihasida ishlatmoqchi. Kutubxonaga o'zgarish kiritib, har safar npm'ga nashr qilish — sekin va noqulay. Kerak bo'lgani: kassa ning node_modules/bahor-narx i to'g'ridan-to'g'ri Sardorning papkasiga qarasin.

Upstream'ga tuzatish yuborishda ham shu kerak: kutubxonani fork qilib, tuzatib, o'z loyihangizda sinab ko'rasiz.

bash
cd bahor-narx
npm link
cd ../kassa
npm link bahor-narx
node chek.js
text
Osh: 35000 so'm

Ikki qadam: birinchi npm link kutubxonani global papkada ro'yxatdan o'tkazadi, ikkinchisi kassa/node_modules/bahor-narx ni symlink qiladi. Symlink (ramziy havola) — boshqa papkaga ishora qiluvchi "yorliq": unga kirsangiz, aslida boshqa joydasiz. Sinov uchun global papkani alohida joyga ko'chirdik (npm_config_prefix), npm buyruqlari darsidagi kabi.

Kutubxonaga minglarni ajratishni qo'shamiz (35000 → 35 000) va kassa da qayta ishga tushiramiz — hech qanday o'rnatishsiz:

text
Osh: 35 000 so'm
bash
npm ls
text
kassa@1.0.0 …\kassa
`-- bahor-narx@1.0.0 extraneous -> .\..\bahor-narx

extraneous — npm buyruqlari darsidagi "diskda bor, package.json da yo'q". npm link package.json ga hech narsa yozmaydi. Shuning uchun keyingi npm install uni o'chiradi. Sardor npm i -E picocolors@1.1.1 qildi:

bash
node chek.js
text
Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'bahor-narx' imported from …\kassa\chek.js

Link yo'qoldi. Yana ikki tuzoq:

  • Ikki nusxa. Kutubxona va loyiha bir xil paketni (masalan, React) ishlatsa, symlink orqali ikki xil node_modules/react paydo bo'ladi. React 17-qismda ko'radigan "Invalid hook call" xatosining eng ko'p uchraydigan sababi — aynan shu.
  • Global holat. Link global papkada qoladi, npm ls -g da ko'rinadi; ishingiz tugagach — npm unlink bahor-narx va kutubxona papkasida npm unlink.

6.4 file: va yalc

Barqarorroq yo'l — papka yo'li bilan o'rnatish:

bash
npm i ../bahor-narx

package.json ga "bahor-narx": "file:../bahor-narx" yoziladi, node_modules da yana symlink, lekin endi u npm install dan keyin ham qoladi. Kamchiligi — yo'l sizning kompyuteringizga xos: jamoadoshda ../bahor-narx bo'lmasligi mumkin. Shuning uchun bunday yozuvni asosiy branch'ga commit qilmaysiz.

yalc — uchinchi yo'l. U symlink emas, nusxa qiladi — xuddi npm'ga nashr qilib, o'rnatgandek, lekin lokal "ombor" orqali:

bash
cd bahor-narx
npx yalc@1.0.0-pre.53 publish
cd ../kassa2
npx yalc@1.0.0-pre.53 add bahor-narx
text
bahor-narx@1.0.0 published in store.
Package bahor-narx@1.0.0 added ==> …\kassa2\node_modules\bahor-narx

Loyihada .yalc/ papkasi, yalc.lock va "bahor-narx": "file:.yalc/bahor-narx" paydo bo'ldi. node_modules/bahor-narx — oddiy papka. Nusxa bo'lgani uchun ikki nusxa muammosi bo'lmaydi va paket npm pack dagidek — faqat nashr qilinadigan fayllar bilan keladi. Kamchiligi: har o'zgarishdan keyin yalc push kerak. Versiyasi hali 1.0.0-pre.53 — loyiha yillardir "pre" holatda, lekin keng ishlatiladi. Global ombor ~/.yalc da, biz sinovda --store-folder bilan boshqa joyga ko'chirdik.

Usul Qanday package.json Qachon
npm link global orqali symlink o'zgarmaydi tez, qisqa sinov
file:../papka to'g'ridan-to'g'ri symlink file: yoziladi lokal ish, commit qilinmaydi
yalc nusxa (nashrga o'xshash) file:.yalc/… ikki nusxa muammosi bo'lsa
pnpm link pnpm'dagi symlink link: pnpm loyihalarda

Tekshirib ko'ring: Sardor npm link bilan sinab, hammasi ishladi deb kutubxonani nashr qildi. Foydalanuvchilarda esa Cannot find module './utils.js' chiqdi. Qanday bo'lishi mumkin?

Javob

Symlink kutubxonaning butun papkasini ko'rsatadi — package.json dagi files ro'yxatiga kirmagan fayllar ham. Nashr qilingan paketda esa faqat files dagilar bor (Kirish nuqtalari darsida). utils.js ro'yxatda yo'q edi. yalc yoki npm pack + .tgz ni o'rnatish bu xatoni nashrdan oldin ko'rsatadi, chunki ular aynan nashr qilinadigan fayllarni ko'chiradi.

7. Upstream'ga yuborish

Yamoq — vaqtinchalik. Doimiy yechim — kutubxonaning o'zida tuzatish. Upstream ("oqim yuqorisi") — kutubxonaning asl reposi. Yo'li:

  1. Mavjud issue'ni qidiring. Ko'pincha kimdir allaqachon yozgan — unga o'z holatingizni qo'shing, yangi nusxa ochmang.
  2. Minimal misol (reproduction). Muammoni ko'rsatadigan eng kichik kod: slugify("Lag‘mon", { lower: true }) → kutilgan lagmon, olingan lag'mon. Versiyalar: slugify 1.6.9, Node 24.21.0. Uzun loyihangiz emas — 5 qator.
  3. Issue. npx patch-package slugify --create-issue yamoqdan qoralama tayyorlaydi. Uni o'qib, o'zingiz to'ldirasiz.
  4. PR. Repo'ni fork qiling, tuzating, test qo'shing, npm link yoki yalc bilan o'z loyihangizda sinang, PR oching.
  5. Kuting va kuzating. Tuzatish chiqqach — yangilang va yamoqni o'chiring.

Muallif sizga hech narsa qarzdor emas: u bepul ishlaydi. Xushmuomala, aniq va qisqa yozilgan issue tezroq ko'rib chiqiladi. Open source'ga hissa qo'shishni kurs oxirida batafsil o'rganamiz.

8. Ko'p uchraydigan xatolar

Xato Oqibati To'g'risi
node_modules ni tahrirlab, saqlamaslik npm ci dan keyin yo'qoladi patch-package yoki pnpm patch
postinstall siz yamoq jamoadoshda qo'llanmaydi yamoq + postinstall bitta commit'da
yamoq qo'llanmadi, lekin exit 0 xato jim o'tadi test + --error-on-fail
overrides — peer xatosini "o'chirish" uchun xato ishlash paytiga ko'chadi sabab va test bilan
file:../… ni commit qilish jamoadoshda yo'l yo'q faqat lokal branch'da

Yana bir ogohlantirish: yamoq yasashdan oldin npx patch-package slugify "There don't appear to be any changes." ("o'zgarish ko'rinmayapti") desa — siz boshqa faylni tahrirlagansiz. Bu ko'pincha kutubxonaning ikki versiyasi bo'lganda yuz beradi (dist/index.js va dist/index.cjs): Node qaysi birini o'qishini Kirish nuqtalari darsidagi exports hal qiladi.

9. Mashqlar

Mashqlar kurs/mashqlar/16/18-tuzatish/ da.

1-mashq (oson): Qaysi vosita?

Har vaziyat uchun vosita tanlang (patch-package, overrides, npm link):

  • Kutubxonadagi bitta qatorni o'zgartirish kerak, tuzatilgan versiya yo'q:
  • Chuqurdagi zaif paketning tuzatilgan versiyasi bor, uni olib keluvchi paket yangilanmagan:
  • O'z kutubxonangizni nashr qilmasdan loyihada sinash:
Yechim

Kod o'zgarishi — yamoq (patch-package yoki pnpm patch). Versiya almashishi — overrides (Yarn'da resolutions). Lokal sinov — npm link (yoki file:, yalc). Uchalasi ham vaqtinchalik: maqsad — upstream'dagi tuzatish va oddiy yangilash.

2-mashq (o'rta): slugify yamog'i

kurs/mashqlar/16/18-tuzatish/menyu/ da slugify@1.6.9 ni o'rnating. Darsdagi yamoqni yasang, postinstall qo'shing, node_modules ni o'chirib npm ci qiling. So'ng ikki savol:

  1. slug.js nima chiqaradi?
  2. Yamoq o'rniga slugify(name, { lower: true, strict: true }) yetarlimidi? Sinab ko'ring.
Yechim
  1. npm ci chiqishida slugify@1.6.9 ✔, slug.js — /menyu/lagmon, /menyu/kok-choy, /menyu/ozbek-palovi.
  2. Ha, bu misolda yetarli edi: strict harf, raqam va ajratgichdan boshqa hamma belgini o'chiradi. Bu darsning muhim saboq'i: yamoqdan oldin kutubxona hujjatini o'qing. Yamoq — API yo'q bo'lganda. Mexanizmni o'rganish uchun mashq qildik; haqiqiy loyihada strict: true ni tanlang va yamoqni o'chiring.

3-mashq (qiyin): Yamoq tekshiruvchisi

patch-tekshir.mjs yozing: loyihaning patches/ papkasidagi har .patch fayl nomidan paket nomi va versiyasini ajratib, node_modules dagi o'rnatilgan versiya bilan solishtirsin.

  • parsePatchName("slugify+1.6.9.patch") → { name: "slugify", version: "1.6.9" }; scope'li nom: "@bahor+narx+2.0.0.patch" → { name: "@bahor/narx", version: "2.0.0" }.
  • checkPatches(root) → [{ name, patched, installed, ok }], nom bo'yicha tartibda; paket o'rnatilmagan bo'lsa installed: null.
  • Buyruq qatoridan ishga tushganda: har yamoqqa ✔ yoki ✖ va hammasi mos bo'lmasa chiqish kodi 1.

Ishoralar: split("+") va pop() — oxirgi bo'lak versiya. existsSync — fayl bormi. package.json dagi versiya — JSON.parse(readFileSync(…, "utf8")).version. Testda vaqtinchalik papka (mkdtempSync) yasab, ichiga soxta patches/ va node_modules/<nom>/package.json yozing.

Yechim
js
// patch-tekshir.mjs — yamoqlar o'rnatilgan versiyaga mosmi
import { existsSync, readdirSync, readFileSync } from "node:fs";
import { join } from "node:path";

// "slugify+1.6.9.patch" → { name: "slugify", version: "1.6.9" }
// "@scope+nom+2.0.0.patch" → name "@scope/nom", version "2.0.0"
export function parsePatchName(file) {
  const parts = file.replace(/\.patch$/, "").split("+");
  const version = parts.pop();
  return { name: parts.join("/"), version };
}

export function checkPatches(root) {
  const dir = join(root, "patches");
  if (!existsSync(dir)) return [];
  const files = readdirSync(dir).filter((f) =>
    f.endsWith(".patch"),
  );
  return files.sort().map((file) => {
    const { name, version } = parsePatchName(file);
    const pkg = join(root, "node_modules", name, "package.json");
    const installed = existsSync(pkg)
      ? JSON.parse(readFileSync(pkg, "utf8")).version
      : null;
    return {
      name,
      patched: version,
      installed,
      ok: installed === version,
    };
  });
}

if (import.meta.main) {
  const report = checkPatches(process.argv[2] ?? ".");
  for (const r of report) {
    const mark = r.ok ? "✔" : "✖";
    console.log(
      `${mark} ${r.name}: yamoq ${r.patched}, bor ${r.installed}`,
    );
  }
  process.exitCode = report.every((r) => r.ok) ? 0 : 1;
}

Ikki test (parsePatchName — oddiy va scope'li nom; checkPatches — mos, mos emas va o'rnatilmagan paket) bilan node --test patch-tekshir.test.mjs — ℹ tests 2, ℹ pass 2, ℹ fail 0. 2-mashqdagi loyihada:

bash
node patch-tekshir.mjs menyu; echo "exit $?"
text
✔ slugify: yamoq 1.6.9, bor 1.6.9
exit 0

npm i -E slugify@1.6.8 dan keyin — ✖ slugify: yamoq 1.6.9, bor 1.6.8 va exit 1. Bu skriptni npm test dan oldin yuritsangiz, patch-package jim o'tkazib yuboradigan holat ushlanadi.

10. Real ishda

  • Katta loyihalarda patches/ papkasi tez-tez uchraydi: React Native, Next.js loyihalarida 3–10 ta yamoq odatiy hol. Har biri — issue havolasi bilan.
  • Xavfsizlik shoshilinchligi: zaiflik e'lon qilindi, tuzatish faqat yangi MINOR'da, chuqurdagi paket esa eski MAJOR'da — overrides bir necha soatda muammoni yopadi.
  • Monorepo (bir repoda bir nechta paket) — npm link o'rniga workspaces ishlatiladi. Buni pnpm darsida ko'rgan edingiz.
  • Intervyu savollari: "Kutubxonadagi xatoni qanday tuzatgan bo'lardingiz?", "overrides qachon kerak?", "npm link ning kamchiliklari?".

Xulosa

  • node_modules ni tahrirlash — npm ci gacha; o'zgarishni patch-package (patches/, postinstall) yoki pnpm patch (patchedDependencies) saqlaydi.
  • Yamoq versiyaga bog'langan: yaqin versiyada — ogohlantirish, uzoqda — xato; patch-package lokalda exit 0 beradi, shuning uchun test va --error-on-fail.
  • overrides — tranzitiv versiyani majburlash; "$nom" to'g'ridan-to'g'ri bog'liqlik bilan EOVERRIDE ziddiyatini yechadi; Yarn'da resolutions.
  • npm link — tez, lekin package.json ga yozilmaydi va npm install uni o'chiradi; file: — barqaror, lekin lokal; yalc — nusxa, nashrga yaqin.
  • Har yamoq — texnik qarz: issue, minimal misol va PR bilan upstream'ga.

Keyingi dars: Modul formatlari: IIFE, UMD, CJS, ESM — kutubxona ichiga nazar tashladik; endi uning dist/ papkasidagi .cjs, .js, .umd.js fayllari nega bir nechta ekanini va bundler ularni qanday o'qishini ko'ramiz.

Manbalar

  • patch-package — github.com/ds300/patch-package (README: "Set-up", --create-issue, --error-on-fail)
  • pnpm: pnpm patch, pnpm patch-commit, patchedDependencies, overrides — pnpm.io/cli/patch, pnpm.io/settings
  • npm Docs (v11): "package.json → overrides", npm link — docs.npmjs.com
  • yalc — github.com/wclr/yalc
  • slugify — github.com/simov/slugify (strict, extend)
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Begona paketni tuzatish: patch-package, overrides va npm link — IlmHamroh