Mundarija (29)
- Bu darsda
- 1. Nega bu kerak?
- 2. npm run ichida nima bo'ladi
- 2.1 Mashq loyihasi
- 2.2 Skript qayerda ishlaydi
- 2.3 Chiqish kodi
- 3. pre va post skriptlar
- 3.1 Tartib
- 3.2 Ovozni pasaytirish va o'chirish
- 3.3 Yo'q skript va --if-present
- 4. Argument uzatish va skript o'zgaruvchilari
- 4.1 -- belgisi
- 4.2 npm beradigan o'zgaruvchilar
- 5. Ketma-ket va parallel
- 5.1 && — ketma-ket
- 5.2 Parallel: run-p va concurrently
- 6. Windows tuzoqlari
- 6.1 Uch klassik xato
- 6.2 Yechimlar
- 6.3 node --run
- 7. Ko'p uchraydigan xatolar
- 8. Mashqlar
- 1-mashq (oson): Tartibni ayting
- 2-mashq (o'rta): Skriptlarni hamma tizimga moslang
- 3-mashq (qiyin): Skript tekshiruvchi
- 4-mashq: Vazifalar qadami — npm run check
- 9. Real ishda
- Xulosa
- Manbalar
npm scripts chuqur: pre/post skriptlar, argumentlar va Windows tuzoqlari
Qisqacha:
package.jsondagiscripts— loyihaning buyruq paneli:npm run nombuyruqninode_modules/.binPATH'ga qo'shilgan holda ishga tushiradi.pre<nom>vapost<nom>skriptlari o'zi oldin va keyin bajariladi, skriptga argument esa--dan keyin beriladi. Windows'da skriptlarcmdda ishlaydi, shuning uchunrm -rf,NODE_ENV=…va bittalik qo'shtirnoq u yerda buziladi —node -e,cross-envyoki--env-filebilan yeching.
Bu darsda
npm runskriptni qanday ishga tushirishini va negaprettierterminalda topilmasa ham skriptda topilishini tushunasiz.pre/postskriptlar tartibini va--ignore-scriptsni bilasiz.- Skriptga argumentni
--bilan to'g'ri uzatasiz vanpm_lifecycle_eventkabi o'zgaruvchilarni o'qiysiz. - Ketma-ket (
&&,run-s) va parallel (run-p,concurrently) ishga tushirishni farqlaysiz. - Windows'da buziladigan skriptlarni taniysiz va
vazifalarganpm run checkqo'shasiz.
Oldin bilishingiz kerak: package.json II: bog'liqlik turlari, npm'ga birinchi qadam, Exit code va buyruqlarni zanjirlash.
1. Nega bu kerak?
vazifalar ni push qilishdan oldin Sardor to'rtta buyruq yozadi: npm run format:check, npm run lint, npm run tip, npm test. Bir kuni u shoshib npm test ni yozdi-yu, lint ni unutdi. CI qizarib ketdi. Jasur aka so'radi: "Nega GitHub'da tekshiradigan narsani kompyuteringda bitta buyruq bilan tekshirmaysan?"
Ikkinchi voqea. Malika Windows'da «Bahor» menyu loyihasini ochdi. Sardor macOS'da yozgan "tozala": "rm -rf dist" skripti uning kompyuterida xato berdi.
npm'ga birinchi qadam darsida scripts ga nom berib, npm run nom qilishni o'rgangansiz. Bugun uning ichini ochamiz: npm skriptni qanday ishga tushiradi, unga nima beradi va qayerda buziladi.
Maslahat: Chiqishlar 2026-10-10 da Windows 11, Node 24.21.0 va npm 11.19.0 bilan olingan. Yo'l boshi
…bilan qisqartirilgan; vaqtlar sizda boshqacha bo'ladi.
2. npm run ichida nima bo'ladi
2.1 Mashq loyihasi
kurs/mashqlar/16/06-skriptlar/ da npm init -y, npm pkg set type=module. menyu.js — dist/menyu.txt ga menyu yozadi:
// menyu.js — «Bahor» menyusini dist/menyu.txt ga yozadi
import { mkdirSync, writeFileSync } from "node:fs";
const menu = ["Osh — 35000", "Lag'mon — 28000", "Manti — 30000"];
mkdirSync("dist", { recursive: true });
writeFileSync("dist/menyu.txt", menu.join("\n") + "\n");
console.log(`dist/menyu.txt: ${menu.length} ta taom`);Skriptlarni npm pkg set bilan qo'shamiz (uning chiqishi yo'q — jim tugaydi):
npm pkg set scripts.prebuild="echo 1-prebuild" \
scripts.build="node menyu.js" scripts.postbuild="echo 3-postbuild"npm run nom berilmasa — ro'yxatni chiqaradi:
npm runLifecycle scripts included in 06-skriptlar@1.0.0:
test
echo "Error: no test specified" && exit 1
available via `npm run`:
prebuild
echo 1-prebuild
build
node menyu.js
postbuild
echo 3-postbuildIkki guruh bor. Lifecycle (hayot sikli) skriptlari — test, start, stop, restart: ular uchun run shart emas, npm test yetadi. Qolganlari faqat npm run nom bilan ishlaydi. Begona loyihani ochganda birinchi buyruq shu — "bu yerda qanday buyruqlar bor?".
2.2 Skript qayerda ishlaydi
npm run build bajarilganda npm uchta ish qiladi:
- Joriy papkadan yuqoriga qarab
package.jsonni topadi va ishchi papkani shu papka qiladi.src/ichida turib hamnpm run buildqilsangiz, skript ildizda ishlaydi. - PATH'ning boshiga
node_modules/.binni qo'shadi. - Skript matnini shellga (buyruq qatori dasturiga) beradi: Windows'da —
cmd.exe, macOS va Linux'da —sh.
Ikkinchi band — ko'p savollarning javobi. rimraf paketini (pastda) o'rnatgandan keyin terminalda:
rimraf --version/usr/bin/bash: line 1: rimraf: command not foundTerminal rimraf ni tanimaydi: u node_modules/.bin ga qaramaydi. Skript ichida esa PATH'ning birinchi papkasi:
…\kurs\mashqlar\16\06-skriptlar\node_modules\.binShuning uchun scripts da npx yozmasdan prettier --check . deyish yetadi. Terminalda esa npx rimraf --version — u ham shu papkaga qaraydi (npx darsida chuqur).
2.3 Chiqish kodi
Skriptning chiqish kodi — npm run ning chiqish kodi. Exit code darsida o'rganganingizdek, 0 — muvaffaqiyat, boshqasi — xato. CI ham, && zanjiri ham aynan shunga qaraydi.
Tekshirib ko'ring: Bobur
vazifalar/assets/js/papkasida turibnpm run lintyozdi. ESLint qaysi papkani tekshiradi?
Javob
Butun loyihani. npm package.json ni yuqoridan topib, skriptni ildiz papkada ishga tushiradi — eslint . dagi . ildizni bildiradi. Faqat assets/js/ kerak bo'lsa, argument bering («Argument uzatish» bo'limi).
3. pre va post skriptlar
3.1 Tartib
build uchun npm avval prebuild, keyin build, oxirida postbuild ni qidiradi:
npm run build
> 06-skriptlar@1.0.0 prebuild
> echo 1-prebuild
1-prebuild
> 06-skriptlar@1.0.0 build
> node menyu.js
dist/menyu.txt: 3 ta taom
> 06-skriptlar@1.0.0 postbuild
> echo 3-postbuild
3-postbuildHar skript oldidan npm ikki qator yozadi: > paket@versiya nom va > buyruq. Bu ham ma'lumot: qaysi skript, qanday matn bilan ishga tushdi.
flowchart LR
A["npm run build"] --> B["prebuild"]
B -- "0" --> C["build"]
C -- "0" --> D["postbuild"]
B -- "0 emas" --> X["to'xtaydi"]
C -- "0 emas" --> XSxemadagi qoida: pre xato bilan tugasa, asosiy skript ishlamaydi. Sinov — prebuild ni node -e "process.exit(1)" qildik:
npm run build
> 06-skriptlar@1.0.0 prebuild
> node -e "process.exit(1)"
Faqat prebuild ishladi, build ga navbat kelmadi, chiqish kodi 1.
pre/post ning kamchiligi — ular yashirin. build ni o'qigan odam prebuild borligini bilmasligi mumkin. Shuning uchun ko'p jamoa ularni kam ishlatadi va zanjirni ochiq yozadi: "build": "node tozala.js && node menyu.js". vazifalar da ham shunday bo'ladi: v5 dagi prebuild (dist'ni tozalash) Vite kelganda olib tashlanadi — Vite dist/ ni o'zi tozalaydi (Bundler nima).
3.2 Ovozni pasaytirish va o'chirish
--silent (-s) npm'ning > qatorlarini yashiradi — faqat skriptlarning o'z chiqishi qoladi:
npm run build --silent1-prebuild
dist/menyu.txt: 3 ta taom
3-postbuild--ignore-scripts esa pre va post ni o'tkazib yuboradi:
npm run build --ignore-scripts
> 06-skriptlar@1.0.0 build
> node menyu.js
dist/menyu.txt: 3 ta taomBu bayroq aslida xavfsizlik uchun yaratilgan: npm install --ignore-scripts paketlarning o'rnatish skriptlarini (postinstall) bloklaydi. Bu haqda Ta'minot zanjiri xavfsizligi darsida.
3.3 Yo'q skript va --if-present
npm run lintnpm error Missing script: "lint"
npm error
npm error Did you mean this?
npm error npm link # Symlink a package folder
npm error
npm error To see a list of scripts, run:
npm error npm run
npm error A complete log of this run can be found in: …\npm-cache\_logs\2026-10-10T14_30_00_445Z-debug-0.log"lint skripti yo'q. Shuni nazarda tutdingizmi: npm link?" npm o'xshash buyruqni taklif qildi, lekin bu umuman boshqa narsa. npm run lint --if-present esa skript yo'q bo'lsa jim tugaydi (chiqish kodi 0). Ko'p loyihalarni bir xil CI bilan tekshirganda qulay.
Tekshirib ko'ring:
"pretest": "npm run lint"va"test": "node --test".npm testda lint xato topsa, testlar ishlaydimi?
Javob
Yo'q. pretest 1 bilan tugaydi va npm test ni boshlamaydi. npm test ham 1 bilan tugaydi. Lekin npm test --ignore-scripts lint'ni chetlab o'tadi — yashirin bog'lanishning yana bir xavfi.
4. Argument uzatish va skript o'zgaruvchilari
4.1 -- belgisi
info.js — skriptga nima kelayotganini ko'rsatadi:
// info.js — npm skriptga qanday ma'lumot beradi?
const env = process.env;
console.log("hodisa:", env.npm_lifecycle_event);
console.log("paket:", env.npm_package_name, env.npm_package_version);
console.log("argumentlar:", process.argv.slice(2));"info": "node info.js". Argument bilan, -- orqali:
npm run info -- --narx 35000 osh
> 06-skriptlar@1.0.0 info
> node info.js --narx 35000 osh
hodisa: info
paket: 06-skriptlar 1.0.0
argumentlar: [ '--narx', '35000', 'osh' ]-- — "bundan keyingisi npm uchun emas, skript uchun". npm uni skript matni oxiriga qo'shdi — ikkinchi > qatorida ko'rinib turibdi. Endi -- siz:
npm run info --narx 35000 oshnpm warn "35000" is being parsed as a normal command line argument.
npm warn Unknown cli config "--narx". This will stop working in the next major version of npm.
> 06-skriptlar@1.0.0 info
> node info.js 35000 osh
hodisa: info
paket: 06-skriptlar 1.0.0
argumentlar: [ '35000', 'osh' ]"--narx — noma'lum npm sozlamasi. Keyingi asosiy versiyada bu ishlamay qoladi". npm -- bilan boshlangan so'zni o'ziga oldi va tashladi. osh kabi oddiy so'zlar -- siz ham o'tadi, lekin bayroqlar — yo'q. Qoida: skriptga bayroq berilsa, doim -- qo'ying.
vazifalar da bu har kuni kerak: 143 ta testdan faqat bittasini yuritish.
npm test -- --test-name-pattern="paketniTekshir"
> test
> node --test --test-name-pattern=paketniTekshir
…
▶ paketniTekshir
✔ paketniTekshir (9.2855ms)
…
ℹ tests 16
ℹ suites 1
ℹ pass 16
ℹ fail 0(Fayl qatorlari qisqartirildi.) 16 ta test — paketniTekshir guruhi. -- siz esa npm bayroqni yutadi va 143 ta test ishga tushadi — xuddi yuqoridagi --narx kabi.
4.2 npm beradigan o'zgaruvchilar
npm skriptga o'nlab muhit o'zgaruvchisi beradi. Ulardan foydalilari:
| O'zgaruvchi | Qiymat (info da) |
|---|---|
npm_lifecycle_event |
ishlayotgan skript nomi: info |
npm_lifecycle_script |
skript matni: node info.js |
npm_package_name |
06-skriptlar |
npm_package_version |
1.0.0 |
| O'zgaruvchi | Qiymat (info da) |
|---|---|
npm_package_json |
package.json ning to'liq yo'li |
npm_command |
run |
npm_config_* |
npm sozlamalari |
INIT_CWD |
npm run yozilgan papka |
npm_lifecycle_event bilan bitta fayl turli skriptlarda turlicha ishlashi mumkin. INIT_CWD esa «Skript qayerda ishlaydi» bo'limidagi "ildizda ishlaydi" qoidasining yechimi: foydalanuvchi qayerda turganini aytadi.
Tuzoq: eski maqolalarda npm_package_config_port, npm_package_scripts_build kabi o'zgaruvchilar uchraydi. npm 7 dan beri package.json ning hamma maydoni emas, faqat name, version va bir nechtasi beriladi. Biz Node 24 da npm_ bilan boshlangan o'zgaruvchilarni sanadik — npm_package_ lardan faqat uchtasi bor edi: json, name, version. Boshqa maydon kerak bo'lsa, npm_package_json dagi faylni o'qing.
Tekshirib ko'ring:
"salom": "node info.js"vanpm run salom -- -s. Skript-sni oladimi yoki npm uni--silentdeb tushunadimi?
Javob
Skript oladi: argumentlar: [ '-s' ]. -- dan keyin npm hech narsani o'zi uchun o'qimaydi. npm run salom -s desangiz esa npm jim rejimga o'tadi va skriptga hech narsa bermaydi.
5. Ketma-ket va parallel
5.1 && — ketma-ket
pishir.js — taomni "pishiradi": nomni yozadi va soniya kutadi.
// pishir.js — taomni "pishiradi": node pishir.js <nom> <soniya>
const [name, seconds] = process.argv.slice(2);
console.log(`${name}: boshlandi`);
setTimeout(() => console.log(`${name}: tayyor`), seconds * 1000);"osh": "node pishir.js osh 2", "choy": "node pishir.js choy 1" va "ketma": "npm run osh && npm run choy":
npm run ketma
> 06-skriptlar@1.0.0 ketma
> npm run osh && npm run choy
> 06-skriptlar@1.0.0 osh
> node pishir.js osh 2
osh: boshlandi
osh: tayyor
> 06-skriptlar@1.0.0 choy
> node pishir.js choy 1
choy: boshlandi
choy: tayyorChoy faqat osh tayyor bo'lgach boshlandi. && — "oldingisi 0 bilan tugasa, keyingisi". Bu cmd da ham, sh da ham bir xil ishlaydi — shuning uchun tekshiruv zanjirlari uchun eng ishonchli yo'l. ; esa sh da "baribir davom et" degani, cmd da esa umuman ajratuvchi emas — skriptlarda ishlatmang.
5.2 Parallel: run-p va concurrently
Ba'zan ikki ish bir vaqtda kerak: masalan, dev server va tur tekshiruvi. sh da & buyruqni fonda ishga tushiradi, cmd da esa & — oddiy ketma-ketlik. Shuning uchun parallel ishga maxsus paketlar ishlatiladi:
npm i -D -E concurrently@10.0.6 npm-run-all2@9.0.3
added 30 packages, and audited 48 packages in 9s
16 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilitiesnpm-run-all2 ikki buyruq beradi: run-s (ketma-ket) va run-p (parallel). "rp": "run-p osh choy":
npm run rp
> 06-skriptlar@1.0.0 rp
> run-p osh choy
> 06-skriptlar@1.0.0 osh
> node pishir.js osh 2
> 06-skriptlar@1.0.0 choy
> node pishir.js choy 1
choy: boshlandi
osh: boshlandi
choy: tayyor
osh: tayyorIkkalasi birga boshlandi, choy (1 soniya) oshdan (2 soniya) oldin tayyor. Bizda ketma 5.2 soniya, rp 3.4 soniya oldi (bir o'lchov; har birida npm'ning ishga tushishi ham bor).
concurrently har qatorga skript nomini yozadi — ko'p chiqishda kim nima deganini ajratish oson. "parallel": "concurrently \"npm:osh\" \"npm:choy\"" (npm: — "shu nomli npm skripti"):
npm run parallel
> 06-skriptlar@1.0.0 parallel
> concurrently "npm:osh" "npm:choy"
[osh]
[osh] > 06-skriptlar@1.0.0 osh
[osh] > node pishir.js osh 2
[osh]
[choy]
[choy] > 06-skriptlar@1.0.0 choy
[choy] > node pishir.js choy 1
[choy]
[osh] osh: boshlandi
[choy] choy: boshlandi
[choy] choy: tayyor
[choy] npm run choy exited with code 0
[osh] osh: tayyor
[osh] npm run osh exited with code 0Terminalda prefikslar rangli. Qachon nima:
| Vazifa | Yo'l |
|---|---|
| tekshiruvlar zanjiri (birinchi xatoda to'xta) | && |
| ko'p skript, ketma-ket, qisqa yozuv | run-s lint tip test |
| dev server + kuzatuvchi | run-p yoki concurrently |
npm-run-all (2 siz) — eski paket, oxirgi versiyasi 4.1.5 2018-yilda chiqqan; uning davomchisi — npm-run-all2. Eski loyihalarda birinchisini uchratsangiz, almashtirish oson: buyruqlar bir xil.
Tekshirib ko'ring:
"check": "run-p lint test". Lint xato topdi. Testlar ishlaydimi?
Javob
Ha, ular allaqachon parallel boshlangan. run-p biri yiqilsa, qolganlarini to'xtatadi va 1 bilan tugaydi, lekin "lint o'tmasa test ham kerak emas" degan tejamkorlik yo'q. Tekshiruv zanjirida && aniqroq: birinchi xatoda to'xtaydi va xato chiqishi aralashmaydi.
6. Windows tuzoqlari
6.1 Uch klassik xato
npm Windows'da skriptni cmd.exe ga beradi. Sardor macOS'da yozgan uchta skript:
{
"scripts": {
"tozala": "rm -rf dist",
"prod": "NODE_ENV=production node muhit.js",
"salom": "echo 'Salom, Bahor'"
}
}Malika'ning kompyuterida (PowerShell'dan):
npm run tozala
> 06-skriptlar@1.0.0 tozala
> rm -rf dist
'rm' is not recognized as an internal or external command,
operable program or batch file.cmd da rm yo'q (uning o'z buyrug'i — rmdir /s /q). Git Bash'dan ishga tushirsangiz, rm topilishi mumkin — Git o'z buyruqlarini PATH'ga qo'shgan bo'lsa. Shuning uchun xato "menda ishlaydi" ko'rinishida yashirinadi.
npm run prod
> 06-skriptlar@1.0.0 prod
> NODE_ENV=production node muhit.js
'NODE_ENV' is not recognized as an internal or external command,
operable program or batch file.NOM=qiymat buyruq — sh sintaksisi: "shu buyruq uchun o'zgaruvchi ber". cmd esa NODE_ENV ni buyruq nomi deb o'yladi.
npm run salom
> 06-skriptlar@1.0.0 salom
> echo 'Salom, Bahor'
'Salom, Bahor'Xato yo'q, lekin qo'shtirnoqlar ham chiqdi: cmd bittalik qo'shtirnoqni tanimaydi. echo "Salom, Bahor" ham cmd da qo'shtirnoq bilan chiqadi — cmd ning echo si matnni boricha yozadi.
6.2 Yechimlar
Eng yaxshi yechim — skriptda shell buyruqlari o'rniga Node. Node hamma tizimda bir xil:
| Muammo | Node bilan | Paket bilan |
|---|---|---|
rm -rf dist |
node -e "fs.rmSync('dist', { recursive: true, force: true })" |
rimraf dist |
NODE_ENV=production … |
node --env-file=.env.production … |
cross-env NODE_ENV=production … |
echo '…' |
node -e "console.log('…')" |
— |
node -e da fs ni import qilish shart emas: Node -e rejimida o'z modullarini nomi bilan beradi. vazifalar ning v5 dagi prebuild skripti aynan shunday yozilgan — u 15-qismdan beri Windows'da ham, CI'dagi Linux'da ham ishlaydi.
--env-file — Node 20.6 dan bor bayroq: fayldagi NOM=qiymat qatorlarini muhit o'zgaruvchisiga aylantiradi. U .env darsidagi dotenv-cli paketining o'rnini bosadi. Fayl yo'q bo'lsa — node: .env.local: not found va chiqish kodi 9. "Bo'lmasa ham mayli" degan holat uchun --env-file-if-exists: .env.local not found. Continuing without it. deb davom etadi.
Paketlar ham ishlaydi:
npm i -D -E cross-env@10.1.0 rimraf@6.1.3
added 17 packages, and audited 18 packages in 4s
4 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilitiesnpm run prod
> 06-skriptlar@1.0.0 prod
> cross-env NODE_ENV=production node muhit.js
NODE_ENV: productionmuhit.js — process.env.NODE_ENV ni chiqaradigan bir qatorli fayl. Lekin narxiga qarang: ikkita kichik ish uchun 17 ta paket. Node bilan yechish mumkin bo'lsa — paket qo'shmang (Paket tanlash darsi shu savolga bag'ishlangan).
npm'da script-shell sozlamasi ham bor: masalan, Windows'da skriptlarni Git Bash bilan yuritish. Lekin u har kompyuterda alohida sozlanadi. Jamoadoshingizda bo'lmasa, skript baribir buziladi — shuning uchun skriptning o'zi hamma joyda ishlashi kerak.
6.3 node --run
Node 22 dan node --run nom ham package.json skriptini ishga tushiradi — npm'siz va tezroq:
node --run builddist/menyu.txt: 3 ta taomFarqiga qarang: 1-prebuild va 3-postbuild chiqmadi. node --run pre/post ni ishga tushirmaydi va npm_* o'zgaruvchilarini umuman bermaydi — faqat NODE_RUN_SCRIPT_NAME va NODE_RUN_PACKAGE_JSON_PATH. Tez tekshiruvlar uchun qulay, lekin pre/post ga tayangan loyihada xulq o'zgaradi.
Tekshirib ko'ring: CI (GitHub Actions) Linux'da ishlaydi. Sardor
"tozala": "rm -rf dist"ni CI'da sinab, "ishlayapti" dedi. Nega bu yetarli emas?
Javob
CI sh da ishlaydi, rm u yerda bor. Windows'dagi jamoadosh esa cmd da 'rm' is not recognized oladi. Skript loyihaning hamma ishtirokchisi uchun yoziladi — node -e yoki rimraf hamma joyda ishlaydi.
7. Ko'p uchraydigan xatolar
| Xabar | Sabab | Davosi |
|---|---|---|
Missing script: "lint" |
skript yo'q yoki nomi xato | npm run bilan ro'yxat |
Unknown cli config "--…" |
bayroq -- siz berildi |
npm run nom -- --bayroq |
'rm' is not recognized |
cmd da Unix buyrug'i |
node -e, rimraf |
'NODE_ENV' is not recognized |
NOM=qiymat cmd da |
--env-file, cross-env |
| Belgi | Sabab | Davosi |
|---|---|---|
| asosiy skript ishlamadi | pre… xato bilan tugadi |
pre… ni tuzating |
prettier: command not found terminalda |
.bin faqat skriptda PATH'da |
npx prettier |
node --run da pre ishlamadi |
node --run pre/post ni bilmaydi |
npm run |
node: .env.local: not found |
--env-file fayli yo'q |
--env-file-if-exists |
8. Mashqlar
Mashqlar kurs/mashqlar/16/06-skriptlar/ da.
1-mashq (oson): Tartibni ayting
package.json da: "prebuild": "echo A", "build": "echo B", "postbuild": "echo C", "pretest": "echo D", "test": "echo E". Har buyruq qaysi harflarni qaysi tartibda chiqaradi?
npm run build --silent:npm test --silent:npm run build --ignore-scripts --silent:node --run build:
Yechim
pre → asosiy → post. --ignore-scripts pre/post ni o'tkazadi, node --run ularni umuman bilmaydi. test — lifecycle skript, shuning uchun npm test da ham pretest ishlaydi. Har harf alohida qatorda chiqadi.
2-mashq (o'rta): Skriptlarni hamma tizimga moslang
«Uch klassik xato» bo'limidagi uchta skriptni (tozala, prod, salom) paket o'rnatmasdan shunday qayta yozingki, ular cmd da ham, sh da ham bir xil ishlasin. prod uchun .env.production fayli yarating. menyu.js va muhit.js — darsdagidek.
Yordam: «Yechimlar» bo'limidagi jadvalning "Node bilan" ustuni. JSON ichida " ni \" deb yozing.
Yechim
Uch skriptni npm pkg set bilan yozamiz (Git Bash'da; qator oxiridagi \ — buyruq keyingi qatorda davom etadi):
npm pkg set scripts.prod="node --env-file=.env.production muhit.js"
npm pkg set scripts.salom="node -e \"console.log('Salom, Bahor')\""
npm pkg set scripts.tozala="node -e \"fs.rmSync('dist', \
{ recursive: true, force: true })\""
npm pkg get scripts{
"tozala": "node -e \"fs.rmSync('dist', { recursive: true, force: true })\"",
"build": "node menyu.js",
"prod": "node --env-file=.env.production muhit.js",
"salom": "node -e \"console.log('Salom, Bahor')\""
}Faylda ichki qo'shtirnoqlar \" bo'lib saqlanadi — JSON qatori ichida qo'shtirnoq shunday yoziladi.
.env.production — bitta qator: NODE_ENV=production. Windows cmd da sinov:
npm run prod
npm run salom
> platforma@1.0.0 prod
> node --env-file=.env.production muhit.js
NODE_ENV: production
> platforma@1.0.0 salom
> node -e "console.log('Salom, Bahor')"
Salom, BahorEndi qo'shtirnoqsiz. Bittalik qo'shtirnoq bu yerda xavfsiz: u "…" ichida turibdi va uni cmd emas, Node o'qiydi. npm run build, keyin npm run tozala — dist/ o'chadi, xato yo'q.
3-mashq (qiyin): Skript tekshiruvchi
tekshiruvchi/ da skriptlar.mjs yozing: findUnixOnly(scripts) — scripts obyektini oladi va [{ name, hint }] qaytaradi (nom bo'yicha tartiblangan). Topsin: buyruq boshidagi rm, cp, mv; NOM=qiymat; bittalik qo'shtirnoq. "…" ichidagi matnni tekshirmasin — node -e "…" xavfsiz. tekshir.mjs — node tekshir.mjs <papka>, muammo bo'lsa chiqish kodi 1. skriptlar.test.mjs — kamida 2 test.
Ishoralar: replace(/"[^"]*"/g, '""') — qo'shtirnoq ichini bo'shatadi (RegExp asoslari). Buyruq boshi — qator boshi yoki && dan keyin.
Yechim
skriptlar.mjs:
// skriptlar.mjs — Windows cmd da ishlamaydigan skriptlarni topadi
// Har qoida: naqsh va o'zbekcha maslahat
const RULES = [
{
pattern: /(^|&&\s*|;\s*)rm\s/,
hint: "rm — rimraf yoki node -e fs.rmSync",
},
{
pattern: /(^|&&\s*|;\s*)(cp|mv)\s/,
hint: "cp/mv — node -e fs.cpSync yoki fs.renameSync",
},
{
pattern: /(^|&&\s*|;\s*)[A-Z_]+=\S*\s/,
hint: "NOM=qiymat — cross-env yoki node --env-file",
},
{
pattern: /'[^']*'/,
hint: "bittalik qo'shtirnoq — cmd uni tushunmaydi",
},
];
// scripts obyekti → [{ name, hint }] (nom bo'yicha tartiblangan).
// "..." ichidagi matn (masalan node -e "...") tekshirilmaydi
export function findUnixOnly(scripts) {
const problems = [];
for (const name of Object.keys(scripts).sort()) {
const outside = scripts[name].replace(/"[^"]*"/g, '""');
for (const rule of RULES) {
if (rule.pattern.test(outside)) {
problems.push({ name, hint: rule.hint });
}
}
}
return problems;
}
const found = findUnixOnly({
tozala: "rm -rf dist",
build: "node menyu.js",
prebuild: "node -e \"fs.rmSync('dist', { recursive: true })\"",
});
console.log(found.map((p) => p.name)); // [ 'tozala' ]Oxirgi uch qator — sinash uchun (faylda shart emas). prebuild ichida ham rm so'zi bor (rmSync), lekin u qo'shtirnoq ichida — tekshirilmadi.
tekshir.mjs:
// tekshir.mjs — ishlatish: node tekshir.mjs [papka]
import { readFileSync } from "node:fs";
import { join } from "node:path";
import { findUnixOnly } from "./skriptlar.mjs";
const dir = process.argv[2] ?? ".";
const pkgText = readFileSync(join(dir, "package.json"), "utf8");
const { scripts = {} } = JSON.parse(pkgText);
const problems = findUnixOnly(scripts);
for (const { name, hint } of problems) {
console.log(`✖ ${name}: ${hint}`);
}
if (problems.length === 0) {
console.log("✔ hamma skript Windows'da ham ishlaydi");
} else {
process.exitCode = 1;
}skriptlar.test.mjs:
// skriptlar.test.mjs — node --test skriptlar.test.mjs
import { test } from "node:test";
import assert from "node:assert/strict";
import { findUnixOnly } from "./skriptlar.mjs";
test("Windows'da ishlamaydiganlar topiladi", () => {
const scripts = {
tozala: "rm -rf dist",
prod: "NODE_ENV=production node muhit.js",
nusxa: "npm run build && cp menyu.txt dist/",
salom: "echo 'Salom'",
};
const problems = findUnixOnly(scripts);
assert.deepEqual(
problems.map((p) => p.name),
["nusxa", "prod", "salom", "tozala"],
);
assert.match(problems[3].hint, /rimraf/);
});
test("xavfsiz skriptlar tegilmaydi", () => {
const scripts = {
tozala: "rimraf dist",
prod: "cross-env NODE_ENV=production node muhit.js",
test: 'node --test --test-name-pattern="osh"',
format: "prettier --write .",
prebuild:
"node -e \"fs.rmSync('dist', { recursive: true })\"",
};
assert.deepEqual(findUnixOnly(scripts), []);
});ℹ tests 2
ℹ pass 2
ℹ fail 02-mashqdagi eski (oldin/) skriptlarda:
node tekshir.mjs ../platforma/oldin✖ prod: NOM=qiymat — cross-env yoki node --env-file
✖ salom: bittalik qo'shtirnoq — cmd uni tushunmaydi
✖ tozala: rm — rimraf yoki node -e fs.rmSyncTuzatilgan (keyin/) da — ✔ hamma skript Windows'da ham ishlaydi, chiqish kodi 0.
4-mashq: Vazifalar qadami — npm run check
«Nega bu kerak?» bo'limidagi muammoni yopamiz: push'dan oldingi to'rt tekshiruv — bitta buyruq, lokalda ham, CI'da ham.
- Branch:
chore/check-skripti - Commit:
chore: npm run check — format, lint, tip va test bitta buyruqda
package.jsonningscriptsoxirigacheckqo'shing: avval format, keyin lint, tur tekshiruvi va testlar —&&bilan..github/workflows/pages.ymlningcheckjob'idagi to'rtrunqatorini bittanpm run checkga almashtiring.npm run checkni ishga tushiring, keyin ataylab formatlanmagan fayl qo'shib, zanjir qayerda to'xtashini ko'ring.
Yechim
package.json — scripts oxiriga, qo'lda yoki buyruq bilan:
npm pkg set scripts.check="npm run format:check \
&& npm run lint && npm run tip && npm test"
npm pkg get scripts.check"npm run format:check && npm run lint && npm run tip && npm test"Tartib bejiz emas: eng tez tekshiruv (Prettier) birinchi, eng uzoq (143 test) oxirida. Xato bo'lsa, tezroq bilasiz.
.github/workflows/pages.yml — check job'i oxiri:
- run: npm ci
# format:check, lint, tip, test — package.json "check" skripti
# (lokalda ham aynan shu buyruq: npm run check)
- run: npm run checkSinov (haqiqiy chiqish, test qatorlari qisqartirilgan). Chiqishda to'rtta > sarlavhani qidiring — format:check, lint, tip, test — ular ketma-ket kelishi va oxirida fail 0 turishi kerak:
npm run check
> check
> npm run format:check && npm run lint && npm run tip && npm test
> format:check
> prettier --check .
Checking formatting...
All matched files use Prettier code style!
> lint
> eslint .
> tip
> tsc --noEmit
> test
> node --test
…
ℹ tests 143
ℹ suites 33
ℹ pass 143
ℹ fail 0> check qatorida versiya yo'q — vazifalar da version maydoni yo'q (pasport darsi). Endi ataylab assets/js/sinov.ts ga const narx =35000 yozdik:
> check
> npm run format:check && npm run lint && npm run tip && npm test
> format:check
> prettier --check .
Checking formatting...
[warn] assets/js/sinov.ts
[warn] Code style issues found in the above file. Run Prettier with --write to fix.Nima bo'ldi? Faqat bitta sarlavha (format:check) chiqdi va Prettier sinov.ts ni ko'rsatdi. Zanjir birinchi halqada to'xtadi, chiqish kodi 1. Lint, tsc va testlar ishlamadi — vaqt tejaldi. sinov.ts ni o'chiring.
Natija: npm test — 143/143, 159 ta brauzer tekshiruvi — 159/159. Ilova xulqi o'zgarmadi.
Commit va PR:
git switch -c chore/check-skripti
npm run check
git add package.json .github/workflows/pages.yml
git commit -m \
"chore: npm run check — format, lint, tip va test bitta buyruqda"
git push -u origin chore/check-skripti
gh pr create --fill
gh pr merge --mergeCommit sarlavhasi — 65 belgi. Diff: 2 fayl, +5 −5. Bundan keyin har push'dan oldin bitta qoida: npm run check.
9. Real ishda
- Begona loyihada birinchi buyruq —
npm run: loyihaning "tugmalar paneli".dev,build,test,lintnomlari deyarli hamma joyda bir xil. - CI va lokal bir xil buyruq — yaxshi amaliyot: "CI'da nima tekshirilsa,
npm run checkham shuni tekshiradi". Ko'p jamoalar shu nomni (check,verify,ci) ishlatadi. - Monorepolarda skriptlar paketlar bo'ylab ishga tushiriladi (
npm run test --workspaces) — pnpm darsida ko'ramiz. - Intervyu: "
npm run build -- --watchdagi--nima?", "pre/postqanday ishlaydi?", "Nega skript Windows'da ishlamaydi?".
Xulosa
npm run nomskriptni loyiha ildizida,node_modules/.binPATH'da bo'lgan holda, Windows'dacmdda, boshqa tizimlardashda ishga tushiradi.pre<nom>→<nom>→post<nom>;preyiqilsa asosiy ishlamaydi;--ignore-scriptsvanode --runularni o'tkazadi.- Skriptga bayroq —
--dan keyin;npm_lifecycle_event,npm_package_name,INIT_CWD— foydali o'zgaruvchilar. - Ketma-ket —
&&yokirun-s; parallel —run-pyokiconcurrently;&va;ga tayanmang. - Windows tuzoqlari:
rm,NOM=qiymat, bittalik qo'shtirnoq —node -e,--env-file, kerak bo'lsarimraf/cross-env. vazifalarda endinpm run check— lokalda va CI'da bitta tekshiruv.
Keyingi dars: package.json IV: kirish nuqtalari — main, module, exports va types: import "paket" yozganingizda qaysi fayl ochilishini paket qanday belgilaydi.
Manbalar
- npm Docs (v11): scripts, npm run, config — script-shell, ignore-scripts
- Node.js Docs (v24):
--run,--env-file - npm-run-all2 — github.com/bcomnes/npm-run-all2; concurrently — github.com/open-cli-tools/concurrently; cross-env, rimraf — npm sahifalari (2026-10 holatiga versiyalar darsda)
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!