IlmHamroh
JavaScript Full-stack/24-qism. Node.js55/55-dars20 daqiqa
Mundarija (38)

Node.js CLI'ni tarqatish: npx, versiya, yangilanish xabari va bitta exe fayl (SEA)

Qisqacha: Node CLI'ni tarqatishning asosiy yo'li — npm paketi: foydalanuvchi npx @login/valyuta kurs bilan o'rnatmasdan ishga tushiradi yoki npm i -g bilan o'rnatadi. Buning uchun paket toza bo'lishi (files, bin, shebang), README va LICENSE bo'lishi va versiya semver bo'yicha oshirilishi kerak. Node o'rnatilmagan kompyuter uchun SEA (Single Executable Application) — Node va skriptni bitta exe faylga yig'ish; bizda valyuta.exe 93.7 MB bo'ldi va 83 ms da ishga tushdi. valyuta 1.0.0 — 61 fayl, 30.2 kB, bog'liqliksiz; haqiqiy npm'ga nashrni o'zingiz qilasiz.

Bu darsda

  • npx paketni qanday topishini va ishga tushirishini tushuntira olasiz.
  • Foydalanuvchiga ko'rinadigan "vitrina"ni — README, LICENSE, versiya — tayyorlaysiz.
  • O'z CLI'ingiz uchun yangilanish tekshiruvini (update-notifier g'oyasi) yoza olasiz.
  • SEA bilan bitta exe fayl yasash yo'lini, narxini va biz topgan uch tuzoqni bilasiz.
  • valyuta ni 1.0.0 versiyasiga olib chiqasiz (holat 55) va nashr qadamlarini bilasiz.

Oldin bilishingiz kerak: O'z npm paketingizni nashr qilish, Interaktiv CLI, Skriptlash va avtomatlashtirish, Semver va bog'liqliklar.

1. Nega bu kerak?

24-qism boshida valyuta bitta faylli skript edi. Endi u — 19 modulli, 42 testli, kesh, oqimlar, interaktiv rejim va jarayon ko'rsatkichi bor vosita. Lekin hozircha u faqat sizning kompyuteringizda ishlaydi.

Do'stingiz Jasur ham kurslarni terminalda ko'rmoqchi. U nima qilishi kerak? git clone, npm install, npm run build, keyin node dist/bin.js? Bu — dasturchi uchun ham noqulay. Yaxshi CLI bitta buyruq bilan ishlaydi: npx @login/valyuta kurs USD.

Tarqatish — ko'rinmas ishlarning yig'indisi: paketning ichida faqat keraklisi, tushunarli README, litsenziya, to'g'ri versiya, yangi versiya chiqqanini aytish. Va bitta qiyin savol: Node o'rnatilmagan odam-chi?

O'xshatish: uyda pishirgan non. Oilangiz yeydi — yetarli. Bozorda sotish uchun esa qadoq, yorliq (tarkibi, sanasi), narx va doimiy sifat kerak. Non o'sha — tarqatish boshqa ish.

2. npm va npx

2.1 Ikki yo'l

flowchart LR
  A["npm registry"] --> B["npx @login/valyuta kurs"]
  A --> C["npm i -g @login/valyuta"]
  B --> D["vaqtinchalik keshga yuklab, bir marta ishga tushiradi"]
  C --> E["PATH'da doimiy valyuta buyrug'i"]
  • npx — "paketni ishga tushir". Paket loyihada o'rnatilgan bo'lsa — o'shani, bo'lmasa registry'dan npm keshiga yuklab oladi. Bir martalik ishlatish va har doim eng yangi versiya uchun qulay.
  • npm i -g — global o'rnatish. Har kuni ishlatadigan vosita uchun: har safar yuklanmaydi, tezroq.

npx qaysi buyruqni ishga tushirishini qanday biladi? Paketda bin da bitta buyruq bo'lsa — o'shani (bizda valyuta, paket nomi esa @login/valyuta — nomlar farq qilsa ham ishlaydi).

2.2 Biz sinadik: boshqa papkada

Haqiqiy registry'ga nashr qilmadik (O'z npm paketingiz darsidagi qaror: hisob va token yo'q, npm pack + o'rnatish). Yakuniy holatni @login/valyuta nomi bilan qadoqladik va bo'sh papkaga o'rnatdik (Node 24.21.0, npm 11.19.0, Windows):

text
$ npm pack
npm notice filename: login-valyuta-1.0.0.tgz
npm notice package size: 30.2 kB
npm notice unpacked size: 112.8 kB
npm notice total files: 61
$ npm i C:/Users/…/login-valyuta-1.0.0.tgz
$ ls node_modules/.bin
valyuta
valyuta.cmd
valyuta.ps1
$ npx valyuta --version
1.0.0
$ npx @login/valyuta --version
1.0.0
$ VALYUTA_OFFLINE=1 npx valyuta 100 USD
Ogohlantirish: offline rejim — saqlangan namuna kurslar (fixtures/) ishlatildi
100.00 USD = 1 190 315.00 UZS

Kanon (55-yakuniy.txt) xuddi shunday sinovda haqiqiy CBU'dan ham kurs oldi: npx valyuta kurs USD → 2026-10-23 holatiga (api), exit 0. O'rnatilgan paket — 1 paket, 0.1 MB: bog'liqliklar yo'q, foydalanuvchi faqat valyuta ni yuklaydi.

Paket o'rnatilmagan bo'sh papkada esa:

text
$ npx --yes @login/valyuta --version
npm error code E404
npm error 404 Not Found - GET https://registry.npmjs.org/@login%2fvalyuta - Not found

Tarjimasi: "topilmadi". npx registry'dan qidirdi — paket hali nashr qilinmagan. Nashrdan keyin aynan shu buyruq ishlaydi.

2.3 Biz topgan Git Bash tuzog'i

Kanon (55-yakuniy.txt) bitta jim xatoga duch keldi. Git Bash'da POSIX yo'l bilan:

bash
npm i /c/Users/…/valyuta-1.0.0.tgz

npm xato bermadi, lekin hech narsa o'rnatmadi. Keyingi npx valyuta esa mahalliy paketni topmay registry'ga ketdi va E404 berdi. Windows yo'li (C:/Users/…/valyuta-1.0.0.tgz) bilan hammasi ishladi. npm — Windows dasturi: Git Bash'ning /c/... yo'llarini u har doim ham tushunmaydi. Git Bash'da yo'lni cygpath -m bilan Windows ko'rinishiga o'tkazing yoki nisbiy yo'l (../login-valyuta-1.0.0.tgz) ishlating. Arxiv nomiga e'tibor bering: kanon chiqishida valyuta-1.0.0.tgz (kanon loyiha nomi o'zgarmagan), sizda esa login-valyuta-1.0.0.tgz bo'ladi.

Tekshirib ko'ring: Jasur npx @login/valyuta kurs ni har kuni 10 marta ishlatadi. Unga qaysi yo'lni tavsiya qilasiz?

Javob

npm i -g @login/valyuta. npx ham keshdan foydalanadi, lekin har chaqiruvda registry'dan versiyani tekshirishi mumkin — sekinroq va internet talab qiladi. Global o'rnatilgan buyruq to'g'ridan ishga tushadi (~100 ms). npx — sinab ko'rish yoki kamdan-kam ishlatish uchun.

3. Vitrina: README, LICENSE, versiya

3.1 README

npmjs.com sahifasida va GitHub'da foydalanuvchi birinchi bo'lib README ni ko'radi. valyuta README bo'limlari (holat 55, 2.2 kB):

Bo'lim Nima uchun
Kirish (1–2 gap) Bu nima va manba qayer (CBU, rasmiy emas)
O'rnatish npm install --global, npx, Node 24+
Foydalanish Har buyruq — bitta misol qatori
Exit kodlar 0, 1, 2, 130 — skript yozuvchilar uchun
Sozlash config.json, VALYUTA_*, kesh papkalari har OS'da
Kutubxona sifatida import { kurslarniOl } …
Ishlab chiqish npm run dev/check/build/paket:tekshir

Muhim qator — ogohlantirish: "Rasmiy emas — kurslarni muhim qarorlar uchun cbu.uz saytida tekshiring." CLI xato qilishi mumkin, foydalanuvchi buni bilishi kerak.

3.2 LICENSE

Litsenziya — boshqalar kodingizni nima qila olishi haqidagi huquqiy matn. Litsenziyasiz kod — sukut bo'yicha "hamma huquqlar himoyalangan": hech kim uni qonuniy ishlata olmaydi. valyuta — MIT: istalgan maqsadda foydalanish, o'zgartirish, sotish mumkin, faqat mualliflik yozuvi saqlansin va kafolat yo'q. Kanon faylida:

text
MIT License

Copyright (c) 2026 <Ism Familiya>

<Ism Familiya> o'rniga o'z ismingizni yozing. package.json dagi "license": "MIT" bilan bir xil bo'lsin — npm sahifasi shuni ko'rsatadi. Boshqa keng tarqalganlari: Apache-2.0 (patent bandi bilan), GPL (o'zgartirilgan kod ham ochiq bo'lishi shart).

3.3 Versiya: 0.x dan 1.0.0 ga

Semver bo'yicha 0.x — "hali barqaror emas, har narsa o'zgarishi mumkin". 1.0.0 — va'da: buyruqlar, bayroqlar, exit kodlar va kutubxona API endi faqat major versiyada buziladi. CLI uchun "ommaviy API" — bu buyruq qatori ham: --format ni --chiqish-turi ga o'zgartirish — major o'zgarish, chunki kimningdir skripti buziladi.

Chiqarish tartibi (npm version ni npm paket darsida ko'rgansiz):

bash
npm run check
npm version 1.0.0          # package.json + git commit + v1.0.0 tegi
npm publish --access public   # prepublishOnly: check + paket:tekshir
git push --follow-tags

--version raqami package.json dan o'qiladi (import paket from "../package.json" with { type: "json" }) — qo'lda yozilgan ikkinchi nusxa yo'q, shuning uchun ular ajralib qolmaydi. paket-tekshir.mjs buni ham tekshiradi (Skriptlash).

4. Yangilanish xabari

4.1 G'oya

Foydalanuvchi 1.0.0 ni o'rnatdi va unutdi. Siz 1.1.0 da muhim xatoni tuzatdingiz. U buni qanday biladi? update-notifier (npm view bo'yicha 7.3.1, 2026-10-23; biz o'rnatmadik) kabi kutubxonalar CLI ishga tushganda registry'dagi oxirgi versiyani tekshiradi va stderr'ga xabar beradi:

text
Yangi versiya bor: 1.0.0 → 1.1.0. Yangilash: npm i -g @login/valyuta

Registry har paketning oxirgi versiyasini JSON'da beradi: https://registry.npmjs.org/<paket>/latest. Qolgani — versiyalarni solishtirish.

4.2 Versiyalarni solishtirish

Satr sifatida solishtirish xato: "1.10.0" < "1.9.0" — true (birinchi farq qiluvchi belgi 1 va 9). Raqamlarga bo'lib solishtiramiz:

js
function versiyaFarqi(a, b) {
  const x = a.split(".").map(Number);
  const y = b.split(".").map(Number);
  for (let i = 0; i < 3; i++) {
    if (x[i] !== y[i]) return x[i] < y[i] ? -1 : 1;
  }
  return 0;
}

function yangilanishXabari(joriy, oxirgi, paket) {
  if (versiyaFarqi(joriy, oxirgi) >= 0) return null;
  const tur = joriy.split(".")[0] !== oxirgi.split(".")[0]
    ? " (major — o'zgarishlarni o'qing)"
    : "";
  return `Yangi versiya bor: ${joriy} → ${oxirgi}${tur}. ` +
    `Yangilash: npm i -g ${paket}`;
}

console.log("1.10.0" < "1.9.0");
console.log(versiyaFarqi("1.10.0", "1.9.0"));
console.log(yangilanishXabari("1.0.0", "1.1.0", "@login/valyuta"));
console.log(yangilanishXabari("1.4.2", "2.0.0", "@login/valyuta"));
console.log(yangilanishXabari("1.1.0", "1.1.0", "@login/valyuta"));

Konsolda:

text
true
1
Yangi versiya bor: 1.0.0 → 1.1.0. Yangilash: npm i -g @login/valyuta
Yangi versiya bor: 1.4.2 → 2.0.0 (major — o'zgarishlarni o'qing). Yangilash: npm i -g @login/valyuta
null

Bu soddalashtirilgan: 1.0.0-beta.1 kabi oldindan chiqarilgan versiyalarni bilmaydi. Haqiqiy loyihada npm'ning o'z semver paketi ishlatiladi.

4.3 Qoidalar: xalaqit bermaslik

Yangilanish tekshiruvi ham tarmoq so'rovi — CLI'ni sekinlashtirmasin va skriptlarni buzmasin:

  • Kuniga bir marta. Oxirgi tekshiruv vaqtini kesh papkasiga yozing (path va os — kesh joyi).
  • Fonda yoki qisqa chegara bilan. AbortSignal.timeout(1000) — javob bo'lmasa, jim o'tib ketish.
  • Faqat TTY'da va stderr'ga. Quvurda va CI'da (CI o'zgaruvchisi) — umuman yo'q (Interaktiv CLI).
  • O'chirish imkoni. update-notifier kelishuvi: NO_UPDATE_NOTIFIER=1 yoki --no-update-notifier.
  • Maxfiylik. So'rov — registry'ga, boshqa joyga emas; foydalanuvchi haqida hech narsa yuborilmaydi.

valyuta 1.0.0 da yangilanish tekshiruvi yo'q — kanonga kirmadi: har ishga tushirishda qo'shimcha so'rov (hatto fonda) va kesh mantiqi, nashr qilinmagan paket uchun esa foydasiz. Mashqda o'zingiz qo'shib ko'rasiz.

Tekshirib ko'ring: Nega yangilanish xabari stdout'ga emas, stderr'ga yoziladi?

Javob

stdout — natija: valyuta kurs all -f csv > kurslar.csv faylida "Yangi versiya bor" qatori bo'lmasligi kerak. Xabar — odam uchun, shuning uchun stderr va faqat TTY'da (CLI anatomiyasi).

5. Bitta exe fayl: SEA

5.1 Nega

npm yo'li Node o'rnatilganini talab qiladi. Buxgalter Malika opa uchun "avval Node 24 ni o'rnating" — to'siq. SEA (Single Executable Application, bitta bajariladigan ilova) — Node'ning o'zi va sizning skriptingiz bitta faylda. Ikki marta bosiladi yoki terminalda valyuta.exe kurs USD — Node kerak emas.

Bu Node 24 ning o'rnatilgan imkoniyati. Node 24 hujjatida u "Stability: 1.1 — Active development" (faol ishlab chiqilmoqda) deb belgilangan — API o'zgarishi mumkin. Avval pkg, nexe kabi tashqi vositalar shuni qilardi.

5.2 Qadamlar va biz topgan tuzoqlar

Kanon tajribasi (t55-sea.txt, holat 46 kodi, v0.2.0) — Windows:

flowchart TD
  A["src/*.ts"] --> B["esbuild: bitta CommonJS fayl"]
  B --> C["sea-config.json → sea-prep.blob"]
  C --> D["node.exe nusxasi → valyuta.exe"]
  D --> E["postject: blob'ni exe ichiga"]
  E --> F["valyuta.exe 93.7 MB"]

1. Bitta CommonJS fayl. Node 24 SEA faqat bitta CommonJS skriptni oladi — import lar va bir nechta fayl emas. Kanon esbuild (0.28.2) bilan yig'di. Birinchi urinish:

text
Top-level await is currently not supported with the "cjs" output format

bin.ts dagi top-level await (ES Modules) CommonJS'da mumkin emas. Yechim — alohida kichik CJS kirish fayli: u main() ni chaqiradi va natijani process.exitCode ga yozadi.

2. import.meta.url bo'sh. Ikkinchi urinish:

text
TypeError: Invalid URL

Fixture yo'li new URL("../fixtures/…", import.meta.url) bilan topiladi. CommonJS'da import.meta yo'q — esbuild uni bo'sh qiymatga almashtirdi. Yechim — kichik "shim": import.meta.url o'rniga pathToFileURL(__filename).href. Natijada fixture exe yonidagi ../fixtures dan o'qildi. To'g'ri yo'l — fayllarni exe ichiga sea-config dagi assets bilan qo'shib, sea.getAsset() bilan o'qish (hujjat bo'yicha; sinalmagan).

3. Imzo buzildi. Blob'ni exe ichiga postject (1.0.0-alpha.6 — yagona versiyalari alpha, 2023 yildan) yozadi:

text
warning: The signature seems corrupted!

node.exe Node jamoasi tomonidan raqamli imzolangan. Ichiga yozilgach, imzo endi mos emas. exe baribir ishladi — hujjat ham shuni aytadi: imzosiz binar ishga tushadi, imzoni avval signtool bilan olib tashlash mumkin, aks holda postject ogohlantirishini e'tiborsiz qoldirish kerak. Lekin imzosiz faylga Windows SmartScreen va antiviruslar shubha bilan qaraydi. Uni o'z sertifikatingiz bilan qayta imzolash kerak (signtool; macOS'da codesign) — sinalmagan.

5.3 Natija va narx

text
$ ./valyuta.exe --version
0.2.0
$ ./valyuta.exe 100 USD --offline
Ogohlantirish: offline rejim — saqlangan namuna kurslar (fixtures/) ishlatildi
100.00 USD = 1 190 315.00 UZS
$ ./valyuta.exe kurs USD
2026-10-23 holatiga (api)
USD    1    11 903.15   -62.36  AQSH dollari

Uchala buyruq ishladi, haqiqiy CBU so'rovi ham. Narx va tezlik:

Sovuq start: valyuta --help
  • node -e 0 (bo'sh)73,3 ms
  • valyuta.exe (SEA)82,6 ms
  • node dist/bin.js95,4 ms

Manba: IlmHamroh kanon o'lchovi t01 va t55, 2026-10-23: Node 24.21.0, Windows 11, i5-12500H; n=10–11, mediana

npm paket SEA exe
Hajm 30.2 kB 93.7 MB
Node kerakmi ha, 24+ yo'q
Sovuq start 95.4 ms 82.6 ms
Yangilash npm i -g yangi exe yuklab olish
OS hammasi bitta paket har OS uchun alohida fayl

Nimaga qarang: exe tezroq ishga tushdi — modullarni diskdan qidirish yo'q, hammasi bitta faylda. Lekin hajmi 3 000 baravar katta: 93.6 MB — node.exe ning o'zi, bizning kod esa 34 KB.

5.4 Windows, macOS, Linux

SEA exe faqat yig'ilgan OS va protsessor uchun ishlaydi: Windows .exe Linux'da ishlamaydi. Uch OS uchun uch fayl kerak. Odatiy yo'l — CI'da (GitHub Actions) har OS uchun alohida ishchi (matrix) bir xil skriptni bajaradi va natijalarni "Release" sahifasiga qo'yadi. macOS'da qo'shimcha: imzolash va Apple tasdiqlashi (notarization) — aks holda tizim faylni ochishga ruxsat bermaydi. Biz faqat Windows'da sinadik; Linux va macOS — hujjat bo'yicha.

Qaror: SEA valyuta kanoniga kirmadi. Asosiy auditoriya — dasturchilar, ularda Node bor; 93.7 MB va imzolash muammosi 30 kB paketning o'rnini bosmaydi. SEA Node'siz foydalanuvchilar (buxgalteriya, ofis) uchun ichki vosita tarqatishda foydali.

6. CLI qadami: valyuta 1.0.0 (holat 55 — yakuniy)

Commit: v1.0.0: README, LICENSE, nashrdan oldingi paket tekshiruvi (scripts/paket-tekshir.mjs)

Holat 55 uch darsni birlashtiradi. Skriptlash darsida yozilgan scripts/paket-tekshir.mjs, paket:tekshir va prepublishOnly skriptlari va ESLint'dagi .mjs tuzatishi; bu darsda — README.md, LICENSE va versiya:

diff
-  "version": "0.2.0",
+  "version": "1.0.0",
bash
git add README.md LICENSE package.json eslint.config.js scripts/
git commit -m "v1.0.0: README, LICENSE, nashrdan oldingi paket tekshiruvi (scripts/paket-tekshir.mjs)"

Web scraping darsi kodga hech narsa qo'shmadi — valyuta API ishlatadi.

6.1 Yakuniy tekshiruv

Kanon tekshiruv-55.txt (Node 24.21.0, npm 11.19.0, tsc 6.0.3):

Tekshiruv Natija
build, tip, lint 0 xato
testlar (node:test) 42/42, 4.8 s
npm pack 61 fayl, 30.2 kB (ochilgan 112.8 kB)
bog'liqliklar prod 0, dev 5 (99 paket, 40.9 MB)
sovuq start --help 94.7 ms, kurs USD 98.1 ms

src/ da 19 modul: bin, cli, buyruq, interaktiv, kurs, manba, kesh, kalit, fayl, joylar, sozlama, sana, format, urinish, tarix, tahlil, jarayon, xato, index.

6.2 Node 22 da nima bo'ladi

engines.node — >=24. Kanon PATH'dagi Node 22.17.0 bilan ham sinadi (node22.txt): dist/bin.js 100 USD --offline — ishladi; src/bin.ts (dev rejimi) — ERR_UNKNOWN_FILE_EXTENSION, chunki 22.17 da type stripping sukut bo'yicha yoqilmagan. Ya'ni foydalanuvchi uchun Node 22 ham yetardi, dasturchi uchun — yo'q. Kanon >=24 ni qoldirdi: va'da qilinmagan narsani va'da qilmaslik uchun.

6.3 Nashr — sizning qadamingiz

Bu qadamni kanon bajarmadi — hisob va token yo'q. Siz o'z npm hisobingiz bilan qilasiz (O'z npm paketingiz darsidagi 2FA va trusted publishing bo'limi bo'yicha):

  1. npmjs.com da hisob, 2FA yoqilgan.
  2. package.json da "name": "@login/valyuta" (login — npm nomingiz). Bu nomni siz O'z npm paketingiz darsida qo'ygansiz va u holat 18 commiti bilan birga ketgan. Kanon loyiha valyuta nomi bilan o'lchangan — shuning uchun kanon chiqishlarida eski nom ko'rinadi.
  3. npm login, keyin npm publish --access public. prepublishOnly avval testlar va paket tekshiruvini bajaradi.
  4. Boshqa kompyuterda: npx @login/valyuta kurs USD.

Biz npm publish --dry-run ni yakuniy holat nusxasida, @login/valyuta nomi bilan ishga tushirdik (Node 24.21.0, npm 11.19.0, Windows 11). prepublishOnly ishladi va … 61 fayl, 29.5 kB … Paket tayyor. deb yozdi. Kanonda (valyuta nomi bilan) shu skript 29.4 kB, npm pack esa 30.2 kB ko'rsatgan. Farq ikki sababdan: skript 1024 ga bo'ladi, npm — 1000 ga; uzunroq nom esa package.json ga bir necha bayt qo'shadi. Oxirida:

text
npm notice Publishing to https://registry.npmjs.org/ with tag latest and default access (dry-run)
+ @login/valyuta@1.0.0

"default access" — scoped paket uchun sukut yopiq (pullik). Shuning uchun haqiqiy nashrda --access public shart. Tokenni hech qachon kodga, README'ga yoki chatga yozmang.

npm qoidalari 2025-yil kuzida qattiqlashdi. GitHub e'lonlariga ko'ra (2025-09-22 va 2025-09-29; 2026-10 holatiga — nashrdan oldin npm hujjatini qayta o'qing):

Mavzu Holat
O'z kompyuterdan nashr 2FA majburiy bo'ladi, uni chetlab o'tish olib tashlanadi
Eski (classic) tokenlar 2025-yil noyabr o'rtasida bekor qilingan, yangisini yaratib bo'lmaydi
Yozish huquqli granular token sukut muddati 7 kun, ko'pi bilan 90 kun
2FA turi yangi ulanishlar uchun TOTP ilovasi emas — WebAuthn / passkey
Trusted publishing (OIDC) npm CLI 11.5.1+ (bizdagi 11.19.0 mos); GitHub Actions, GitLab CI/CD, CircleCI
Provenance trusted publishing bilan avtomatik — faqat ochiq repo va ochiq paket uchun (GitHub Actions, GitLab)

Biz bularning birortasini sinamadik — hisob ham, token ham yaratilmagan.

7. Ko'p uchraydigan xatolar

7.1 npm error 404 npx da

Paket nashr qilinmagan, nom xato yozilgan yoki scoped paket yopiq (--access public siz nashr). Mahalliy sinovda — Git Bash'dagi /c/… yo'l ham sabab bo'lishi mumkin (kanon topilmasi).

7.2 --version boshqa raqam

package.json 1.0.0, CLI 0.2.0 deydi — eski dist/ paketga tushgan (build qilinmagan). prepack: npm run build va paket:tekshir dagi versiya solishtiruvi shuni ushlaydi.

7.3 Litsenziyasiz paket

npm warn … No license field — va huquqiy jihatdan hech kim kodingizni ishlata olmaydi. LICENSE fayli va "license" maydoni.

7.4 SEA: Top-level await is currently not supported with the "cjs" output format

SEA'ga faqat CommonJS. Top-level await ni alohida kirish faylidagi oddiy funksiya chaqiruviga o'tkazing.

7.5 SEA: TypeError: Invalid URL

import.meta.url CommonJS bundle'da bo'sh. Shim yoki sea.getAsset().

7.6 Major o'zgarishni minor deb chiqarish

Bayroq nomini o'zgartirib 1.1.0 chiqardingiz — kimningdir cron skripti tunda yiqildi. CLI interfeysi — ommaviy API: buzsangiz, major.

8. Mashqlar

Mashqlar kurs/mashqlar/24/55-tarqatish/ da.

1-mashq (oson): qaysi versiya?

valyuta 1.0.0 dan keyin har o'zgarish uchun yangi versiyani yozing:

  1. Ogohlantirish matnidagi imlo xatosi tuzatildi.
  2. Yangi --chiqish-tartibi bayrog'i qo'shildi.
  3. kurs buyrug'i kurslar deb o'zgartirildi, eskisi o'chirildi.
  4. Exit kod: tarmoq xatosi 1 o'rniga 3 bo'ldi.
Yechim
  1. 1.0.1 — patch: xatti-harakat o'zgarmadi.
  2. 1.1.0 — minor: yangi imkoniyat, eskisi buzilmadi.
  3. 2.0.0 — major: valyuta kurs ishlatgan skriptlar buziladi. Yumshoqroq yo'l — avval 1.x da kurs ni eskirgan deb belgilash (Diagnostika darsidagi util.deprecate), keyin 2.0.0 da olib tashlash.
  4. 2.0.0 — major: exit kodga tayangan skriptlar boshqacha ishlaydi. Exit kod ham interfeys.

2-mashq (o'rta): kuniga bir marta tekshirish

tekshirishKerakmi({ oxirgi, hozir, env, tty }) funksiyasini yozing: true faqat agar TTY bo'lsa, env.CI va env.NO_UPDATE_NOTIFIER bo'lmasa va oxirgi tekshiruvdan 24 soat o'tgan bo'lsa (oxirgi — millisekund yoki undefined — hech qachon tekshirilmagan). Besh holatni sinang. Yordam: Date farqi millisekundlarda (Date va vaqt zonalari).

Yechim
js
const KUN = 24 * 60 * 60 * 1000;

function tekshirishKerakmi({ oxirgi, hozir, env = {}, tty }) {
  if (tty !== true) return false;
  if (env.CI || env.NO_UPDATE_NOTIFIER) return false;
  if (oxirgi === undefined) return true;
  return hozir - oxirgi >= KUN;
}

const hozir = Date.UTC(2026, 9, 23, 12);
const holatlar = [
  ["birinchi marta", { hozir, tty: true }],
  ["2 soat oldin", { oxirgi: hozir - 2 * 3600e3, hozir, tty: true }],
  ["kecha", { oxirgi: hozir - KUN, hozir, tty: true }],
  ["quvur", { hozir, tty: false }],
  ["CI", { hozir, tty: true, env: { CI: "true" } }],
];
for (const [nom, h] of holatlar) {
  console.log(nom.padEnd(15), tekshirishKerakmi(h));
}

Konsolda:

text
birinchi marta  true
2 soat oldin    false
kecha           true
quvur           false
CI              false

hozir ni parametr qildik — test soatga bog'liq emas. Haqiqiy kodda oxirgi kesh papkasidagi kichik fayldan o'qiladi va tekshiruvdan keyin yangilanadi. CI'da ba'zan TTY "bor" deb ko'rinadi — shuning uchun CI alohida tekshirildi.

3-mashq (qiyin): yangilanish tekshiruvchisi

Asinxron yangilanishniTekshir({ joriy, paket, olish }) funksiyasini yozing. olish(url) — fetch o'rnini bosuvchi funksiya (testda soxta): https://registry.npmjs.org/<paket>/latest dan { version } qaytaradi. Funksiya: yangi versiya bo'lsa — xabar satri, bo'lmasa — null. Xato yoki 1000 ms dan ko'p kutish bo'lsa — jim null (CLI ishi buzilmasin). Scoped nomda / URL'da %2f bo'lsin. Uch soxta olish bilan sinang: yangi versiya, eski versiya, 2 soniya kechikadigan. «Versiyalarni solishtirish» bo'limidagi versiyaFarqi dan foydalaning. Yordam: Promise.race (Promise kombinatorlari), encodeURIComponent.

Yechim
js
function versiyaFarqi(a, b) {
  const x = a.split(".").map(Number);
  const y = b.split(".").map(Number);
  for (let i = 0; i < 3; i++) {
    if (x[i] !== y[i]) return x[i] < y[i] ? -1 : 1;
  }
  return 0;
}

const kut = (ms, qiymat) =>
  new Promise((r) => setTimeout(() => r(qiymat), ms));

async function yangilanishniTekshir(sozlama) {
  const { joriy, paket, olish, ms = 1000 } = sozlama;
  const nom = paket.replace("/", "%2f");
  const url = `https://registry.npmjs.org/${nom}/latest`;
  try {
    const javob = await Promise.race([olish(url), kut(ms, null)]);
    if (!javob) return null; // vaqt tugadi
    if (versiyaFarqi(joriy, javob.version) >= 0) return null;
    return `Yangi versiya: ${joriy} → ${javob.version}`;
  } catch {
    return null; // tarmoq xatosi — CLI ishiga xalaqit bermaymiz
  }
}

const sorovlar = [];
const yangi = async (url) => {
  sorovlar.push(url);
  return { version: "1.1.0" };
};
const eski = async () => ({ version: "1.0.0" });
const sekin = () => kut(2000, { version: "9.9.9" });

const asos = { joriy: "1.0.0", paket: "@login/valyuta" };
for (const olish of [yangi, eski, sekin]) {
  console.log(await yangilanishniTekshir({ ...asos, olish }));
}
console.log(sorovlar[0]);

Konsolda:

text
Yangi versiya: 1.0.0 → 1.1.0
null
null
https://registry.npmjs.org/@login%2fvalyuta/latest

Uchinchi holatda javob 2 soniyada kelardi — Promise.race 1 soniyada null bilan yutdi. Haqiqiy kodda fetch ni AbortSignal.timeout(1000) bilan bekor qilish yaxshiroq — race faqat kutishni to'xtatadi, so'rov esa fonda davom etadi va jarayonni ushlab turishi mumkin (timers). Hamma xato null ga aylanadi: yangilanish tekshiruvi hech qachon asosiy buyruqni yiqitmasligi kerak.

4-mashq: CLI qadami — v1.0.0 va nashr

  1. O'z valyuta ingizga README.md (yuqoridagi bo'limlar jadvali bo'yicha) va LICENSE (MIT, o'z ismingiz) qo'shing, versiyani 1.0.0 qiling.
  2. npm run paket:tekshir — Paket tayyor. chiqsin.
  3. npm pack, boshqa papkada npm i <yo'l>.tgz va npx valyuta --version.
  4. Commit: v1.0.0: README, LICENSE, nashrdan oldingi paket tekshiruvi (scripts/paket-tekshir.mjs).
  5. Xohlasangiz — o'z npm hisobingiz bilan npm publish --access public (2FA bilan) va boshqa kompyuterda npx @login/valyuta kurs USD.
Yechim

Kutilgan raqamlar (kanon): 61 fayl, ~30 kB (README matningizga qarab biroz farq qiladi), o'rnatilgan paket 1 ta, npx valyuta --version → 1.0.0. Git Bash'da tarball yo'lini C:/… ko'rinishida yoki nisbiy yozing — /c/… bilan npm jim hech narsa o'rnatmasligi mumkin. Nashrdan keyin npmjs.com sahifangizda README ko'rinadi; npm view @login/valyuta versiya va bin ni ko'rsatadi. Nashr qilmasangiz ham 1–4 qadamlar loyihani tugatadi: valyuta — tayyor, sinalgan, qadoqlangan CLI.

9. Real ishda

  • Tarqatish kanallari: npm (dasturchilar), Homebrew (macOS), Scoop va winget (Windows), GitHub Releases (exe fayllar). Katta CLI'lar (gh, vercel) bir nechtasidan birdan foydalanadi.
  • Bun va Deno: ikkalasining ham "bitta faylga kompilyatsiya" buyrug'i bor (bun build --compile, deno compile) — Node SEA bilan bir g'oya.
  • Release avtomatlashtirish: changesets yoki semantic-release versiyani, CHANGELOG'ni va nashrni CI'da bajaradi; trusted publishing token saqlamaydi (npm paket).
  • Portfolio: npm'dagi o'z paketingiz — rezyumedagi kuchli satr: kod ochiq, testlar bor, README bor, ishlatib ko'rish bitta buyruq. valyuta ni GitHub'ga va npm'ga qo'ying.

Xulosa

  • npm paket — asosiy yo'l: npx @login/valyuta (bir martalik) yoki npm i -g (doimiy); bin va shebang shart.
  • Vitrina: README (o'rnatish, misollar, exit kodlar, ogohlantirish), LICENSE (MIT), semver — 1.0.0 dan CLI interfeysi ommaviy API.
  • Yangilanish tekshiruvi: kuniga bir marta, qisqa vaqt chegarasi, faqat TTY va stderr, o'chirish imkoni; versiyalarni raqam sifatida solishtiring.
  • SEA: Node'siz bitta exe — 93.7 MB, 83 ms; faqat CommonJS, import.meta.url shim, imzo buziladi; har OS uchun alohida.
  • valyuta 1.0.0: 61 fayl, 30.2 kB, prod bog'liqlik 0, 42/42 test; nashr — sizning qadamingiz.

Keyingi dars: HTTP server tomonda: keep-alive, chunked encoding va curl bilan tahlil — 25-qism boshlanadi: Node'da backend, HTTP so'rov va javobning ichidan.

Manbalar

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Node.js CLI'ni tarqatish: npx, versiya, yangilanish xabari va bitta exe fayl (SEA) — IlmHamroh