IlmHamroh
JavaScript Full-stack/24-qism. Node.js40/55-dars18 daqiqa
Mundarija (28)

Node.js --watch, --env-file va node --run: nodemon va dotenv'siz ishlab chiqish

Qisqacha: Node 24 da uchta kundalik ish uchun paket kerak emas. Birinchisi — node --watch fayl.ts: fayl o'zgarsa dasturni o'zi qayta ishga tushiradi (nodemon o'rniga). Ikkinchisi — node --env-file=.env va process.loadEnvFile(): .env faylini o'qib process.env ga qo'yadi (dotenv o'rniga). Uchinchisi — node --run start: package.json skriptini npm run dan tezroq bajaradi. Lekin u pre/post skriptlarini chaqirmaydi. Bizning o'lchovda valyuta uchun node --run start 266 ms, npm run start 459 ms.

Bu darsda

  • node --watch va --watch-path qaysi fayl o'zgarganda qayta ishga tushishini haqiqiy chiqish bilan ko'rsata olasiz.
  • --env-file, --env-file-if-exists, process.loadEnvFile va util.parseEnv farqini va ustunlik tartibini bilasiz.
  • node --run bilan npm run ni tezlik va xulq bo'yicha solishtirasiz.
  • nodemon va dotenv qachon hali ham kerakligini aniq ayta olasiz.
  • valyuta ga dev va start skriptlarini, .env.example ni qo'shasiz.

Oldin bilishingiz kerak: package.json III: scripts chuqur, YAML, TOML, INI va .env, process obyekti, Loyiha ildizidagi boshqa fayllar.

1. Nega bu kerak?

valyuta ustida ishlayapsiz. Har o'zgarishdan keyin terminalga qaytib, node src/bin.ts kurs USD ni qayta yozasiz. Kuniga yuz marta. Keyin tarmoqsiz sinash uchun VALYUTA_OFFLINE=1 kerak bo'ladi — uni har safar buyruq oldiga yozish ham joniga tegadi.

Bir necha yil oldin bu muammolar uchun uchta paket o'rnatilardi:

Muammo Eski yechim Node 24 da
Fayl o'zgarsa qayta ishga tushirish nodemon node --watch
.env faylini o'qish dotenv --env-file, process.loadEnvFile()
Skriptni tez bajarish npm run node --run

Har paket — yana bitta bog'liqlik, yana bitta yangilanish va xavfsizlik darsidagi yetkazib berish zanjiri xavfi. valyuta ning prod bog'liqliklari soni hozir 0. Shu darsdan keyin dev tomonda ham yangi paket qo'shilmaydi.

O'xshatish: avval choynak, plita va gugurt alohida sotib olinardi. Endi elektr choynak — hammasi bitta qurilmada. Lekin oshxonada katta qozon kerak bo'lsa, baribir alohida plita olasiz. nodemon va dotenv ham shunday: ko'p holatda kerak emas, ba'zi holatda hali ham foydali.

2. node --watch: o'zgarsa — qayta ishga tushir

2.1 Birinchi sinov

Kichik loyiha yasadik: src/app.mjs boshqa fayldan (src/kurs.mjs) kursni import qiladi. Keyin node --watch src/app.mjs ni ishga tushirib, kurs.mjs ni o'zgartirdik. Biz ishga tushirdik (Node 24.21.0, Windows 11):

bash
node --watch src/app.mjs
text
kurs: 11903.15 | env: undefined
Completed running 'src/app.mjs'. Waiting for file changes before restarting...
Change detected in 'C:\\Users\\…\\w\\src\\kurs.mjs'
Restarting 'src/app.mjs'
kurs: 12000 | env: undefined
Completed running 'src/app.mjs'. Waiting for file changes before restarting...

Qatorma-qator:

  • Completed running … — dastur tugadi, lekin Node chiqib ketmadi. U "fayllarni kuzatib, kutyapman" deydi.
  • Change detected in … — o'zgargan fayl. Yo'lda ikkita teskari chiziq — Node shunday chiqaradi, xato emas.
  • Restarting … — jarayon noldan qayta ishga tushdi va yangi kurs (12000) chiqdi.

Hujjatga ko'ra --watch 22.0.0 dan beri barqaror (Stable) — eksperimental emas. Server kabi uzoq ishlaydigan dasturda Node eski jarayonni to'xtatib, yangisini boshlaydi. valyuta bir zumda tugaydi, shuning uchun har safar Completed running ko'rinadi.

2.2 Qaysi fayllar kuzatiladi?

--watch hamma faylni emas, faqat kirish fayli va u import qilgan modullar daraxtini kuzatadi. Shuning uchun biz ataylab import qilinmagan fixtures/data.json ni ham o'zgartirdik:

text
>>> fixtures/data.json o'zgardi

Ostida hech narsa chiqmadi — qayta ishga tushish bo'lmadi. Node bu faylni "loyihaga tegishli" deb bilmaydi, chunki kod uni import qilmagan. readFile bilan o'qilgan JSON, shablon yoki CSV ham shunday — ular kuzatilmaydi.

flowchart LR
  A["src/app.mjs<br/>(kirish)"] -->|import| K["src/kurs.mjs"]
  A -.->|readFile| F["fixtures/data.json"]
  W["node --watch"] -->|kuzatadi| A
  W -->|kuzatadi| K
  W -.-x|kuzatmaydi| F

Rasmda uzluksiz chiziq — import, ya'ni Node biladigan bog'lanish. Uzuq chiziq — kod ichida o'qilgan fayl: --watch uni ko'rmaydi.

2.3 --watch-path: o'zingiz ko'rsatasiz

Fayl yoki papkani aniq berish mumkin. Bu bayroq bo'lsa, Node import daraxtini kuzatmaydi — faqat ko'rsatilgan yo'lni:

bash
node --watch-path=fixtures src/app.mjs

Chiqishda >>> bilan boshlangan qatorlar — biz qaysi faylni o'zgartirganimiz haqidagi belgi. Ularning har biridan keyin Restarting bor-yo'qligiga qarang:

text
kurs: 12000 | env: undefined
Completed running 'src/app.mjs'. Waiting for file changes before restarting...
>>> src/kurs.mjs o'zgardi
>>> fixtures/data.json o'zgardi
Change detected in 'C:\\Users\\…\\w\\fixtures\\data.json'
Restarting 'src/app.mjs'
kurs: 13000 | env: undefined
Completed running 'src/app.mjs'. Waiting for file changes before restarting...

E'tibor bering: src/kurs.mjs o'zgarganda hech narsa bo'lmadi. Keyin fixtures/data.json o'zgardi — qayta ishga tushdi va ikkala o'zgarish ko'rindi (13000).

Qadam Nima o'zgardi Kuzatiladimi? Konsolda
1 — (birinchi ishga tushish) — kurs: 12000
2 src/kurs.mjs yo'q hech narsa
3 fixtures/data.json ha Change detected …, Restarting …
4 qayta ishga tushdi — kurs: 13000

Diqqat: Node 24 hujjatida --watch-path "faqat macOS va Windows'da qo'llab-quvvatlanadi" deb yozilgan; boshqa tizimda ERR_FEATURE_UNAVAILABLE_ON_PLATFORM xatosi chiqadi. Biz faqat Windows'da sinadik, Linux'da sinalmagan. Oddiy --watch esa hamma tizimda ishlaydi.

2.4 Ekran tozalanishi va xato

Hujjatga ko'ra, terminalda (TTY) Node har qayta ishga tushishdan oldin ekranni tozalaydi. Eski chiqish kerak bo'lsa — --watch-preserve-output. Biz chiqishni quvur orqali o'qidik (TTY emas), u yerda tozalash umuman bo'lmadi — shuning uchun yuqoridagi chiqishlar to'liq.

Dastur xato bilan yiqilsa, --watch to'xtamaydi:

text
Error: buzildi

Node.js v24.21.0
Failed running 'crash.mjs'. Waiting for file changes before restarting...

Failed running — dastur xato bilan tugadi, Node esa tuzatishingizni kutyapti. Faylni saqlaysiz — yana ishga tushadi.

Tekshirib ko'ring: valyuta sozlamani config.json dan readFile bilan o'qiydi. Siz config.json ni o'zgartirdingiz, node --watch src/bin.ts esa qayta ishga tushmadi. Nega va qanday tuzatasiz?

Javob

--watch faqat import daraxtini kuzatadi, readFile bilan o'qilgan fayl unga kirmaydi. Tuzatish: --watch-path bilan ikkala joyni ham bering — node --watch-path=src --watch-path=<sozlama papkasi> src/bin.ts. Lekin --watch-path bo'lsa, import daraxti avtomatik kuzatilmaydi — shuning uchun src ni ham yozish shart.

3. .env faylini o'qish

3.1 --env-file

.env formatini bilasiz: KALIT=qiymat qatorlari. Node 24 uni o'zi o'qiydi:

text
VALYUTA_OFFLINE=1
# izoh
VALYUTA_KUTISH=2000
SALOM="Assalomu alaykum"
bash
node --env-file=.env env.mjs
text
1 2000 Assalomu alaykum

env.mjs uchta qiymatni process.env dan chiqardi. Qiymatlar doim matn ("1", "2000") — son kerak bo'lsa, o'zingiz o'girasiz va tekshirasiz.

3.2 Kim ustun?

Bir xil kalit ikki joyda bo'lsa-chi? Biz uchta holatni sinadik:

bash
VALYUTA_KUTISH=99 node --env-file=.env env.mjs
printf 'VALYUTA_KUTISH=3000\n' > .env.local
node --env-file=.env --env-file=.env.local env.mjs
text
1 99 Assalomu alaykum
1 3000 Assalomu alaykum

Qoidasi:

  1. Terminal (yoki tizim) bergan haqiqiy muhit o'zgaruvchisi har doim ustun — 99.
  2. Bir nechta --env-file bo'lsa, keyingisi oldingisini bosadi — 3000.
flowchart TB
  S["1. Shell / tizim muhiti<br/>VALYUTA_KUTISH=99"] --> P["process.env"]
  L["2. --env-file=.env.local<br/>(keyingi fayl)"] --> P
  E["3. --env-file=.env<br/>(birinchi fayl)"] --> P

Yuqoridagi tugun eng kuchli. Bu Next.js'dagi tartibga o'xshaydi (Env o'zgaruvchilar Next.js'da): haqiqiy muhit fayldan ustun. Sabab bir xil — serverda (masalan Docker'da) qiymat tashqaridan beriladi, fayldagi qiymat faqat zaxira.

3.3 Fayl yo'q bo'lsa

bash
node --env-file=yoq.env env.mjs
text
…\node.exe: yoq.env: not found

Dastur umuman boshlanmadi, exit kod 9 (Node'da "noto'g'ri argument"). Bu ko'pincha to'g'ri xulq: .env siz ishlamaydigan server jim ishga tushib ketmaydi.

valyuta uchun esa .env ixtiyoriy — o'quvchi uni yaratmasligi ham mumkin. Buning uchun --env-file-if-exists:

bash
node --env-file-if-exists=yoq.env env.mjs
echo $?
text
yoq.env not found. Continuing without it.
undefined undefined undefined
0

Birinchi qator stderr'ga chiqadi ("topilmadi, usiz davom etaman"), dastur esa ishlaydi. Bu ogohlantirishni har safar ko'rasiz — keyinroq valyuta da ham ko'rinadi.

3.4 Format tafsilotlari: util.parseEnv

Node .env ni qanday tushunadi? node:util dagi parseEnv matnni obyektga aylantiradi — --env-file ham aynan shu qoidani ishlatadi. Bu blokni o'z terminalingizda ishga tushiring (saytdagi natija oynasi brauzer, unda node:util yo'q):

js
import { parseEnv } from "node:util";

const text = [
  "# valyuta sozlamalari",
  "VALYUTA_OFFLINE=1",
  "VALYUTA_KUTISH = 2000",
  "BOSH=",
  "IZOHLI=5000 # millisekund",
  'QOSHTIRNOQ="ikki # so\'z"',
  "BITTA='satr\\nyangi qator emas'",
  'IKKI="satr\\nyangi qator"',
  "export ESKI=ha",
].join("\n");

console.log(parseEnv(text));

Konsolda:

text
{
  BITTA: 'satr\\nyangi qator emas',
  BOSH: '',
  ESKI: 'ha',
  IKKI: 'satr\nyangi qator',
  IZOHLI: '5000',
  QOSHTIRNOQ: "ikki # so'z",
  VALYUTA_KUTISH: '2000',
  VALYUTA_OFFLINE: '1'
}

Har qatordan bitta qoida:

Yozuv Natija Qoida
# … yo'q izoh qatori
VALYUTA_KUTISH = 2000 '2000' = atrofidagi bo'sh joy kesiladi
BOSH= '' bo'sh satr — "yo'q" emas
IZOHLI=5000 # … '5000' qator oxiridagi izoh kesiladi
"ikki # so'z" ikki # so'z qo'shtirnoq ichida # — oddiy belgi
'satr\n…' \n o'zgarmaydi bittalik qo'shtirnoqda escape yo'q
"satr\n…" haqiqiy yangi qator qo'shtirnoq ichida \n ishlaydi
export ESKI=ha 'ha' shell uslubidagi export e'tiborsiz

Kalitlar alifbo tartibida chiqdi — bu Node'ning obyektni ko'rsatish usuli. Muhimi BOSH: '': kalit bor, lekin qiymati bo'sh. Next.js env darsida bo'sh qiymat Zod tekshiruvini buzganini ko'rgansiz — Node'da ham "" va "berilmagan" har xil narsa.

3.5 process.loadEnvFile: koddan o'qish

Bayroqni har buyruqqa yozish o'rniga, .env ni dastur ichidan ham yuklash mumkin:

js
import { writeFileSync } from "node:fs";

writeFileSync(".env", "VALYUTA_KUTISH=2000\n");
process.loadEnvFile(); // sukut bo'yicha ./.env
console.log(process.env.VALYUTA_KUTISH);

try {
  process.loadEnvFile("yoq.env");
} catch (error) {
  console.log(error.code);
}

Konsolda:

text
2000
ENOENT

Farqlar:

  • loadEnvFile() fayl bo'lmasa oddiy JS xatosini (ENOENT) tashlaydi — try/catch bilan ushlaysiz. --env-file esa dasturni boshlamaydi ham.
  • U kod ishlay boshlagandan keyin chaqiriladi. Undan oldin baholangan modullar (masalan, statik import qilingan fayl yuqori darajada process.env ni o'qigan bo'lsa) eski qiymatni ko'rgan bo'ladi. Shuning uchun CLI'da bayroq ishonchliroq.

Tekshirib ko'ring: .env da VALYUTA_KUTISH=5000, terminalda VALYUTA_KUTISH=100 node --env-file=.env src/bin.ts. Dastur qaysi qiymatni ko'radi? .env da VALYUTA_KUTISH= (bo'sh) bo'lsa-chi va terminalda hech narsa berilmasa?

Javob

Birinchisi — "100": haqiqiy muhit .env dan ustun. Ikkinchisi — "" (bo'sh satr), undefined emas. Kodingiz Number("") qilsa — 0 chiqadi, ya'ni "0 ms kut" — jim xato. Shuning uchun qiymatni o'qiganda bo'sh satrni ham "berilmagan" deb hisoblang: env.VALYUTA_KUTISH || undefined.

4. node --run: skriptni tez bajarish

4.1 Asosiy farq

npm run ni bilasiz. node --run ham package.json dagi scripts ni bajaradi, lekin npm'ni umuman yuklamaydi. Biz uchta skriptli kichik loyihada sinadik (nomi.mjs ikki o'zgaruvchini chiqaradi: npm_lifecycle_event va NODE_RUN_SCRIPT_NAME):

json
{
  "scripts": {
    "prestart": "node -e \"console.log('prestart ishladi')\"",
    "start": "node ism.mjs",
    "salom": "node nomi.mjs"
  }
}
bash
node --run start -- kurs USD
npm run start -- kurs USD

Ikki buyruqning chiqishi ketma-ket keltirilgan. Birinchi qatordan keyingi hamma narsa — npm run niki. prestart so'zini qidiring:

text
argv: kurs USD

> prestart
> node -e "console.log('prestart ishladi')"

prestart ishladi

> start
> node ism.mjs kurs USD

argv: kurs USD

Birinchi qator — node --run: faqat dasturning o'z chiqishi. -- dan keyingi argumentlar skriptga o'tdi. npm run esa ikki narsa qo'shdi: buyruq sarlavhalari (> start) va prestart skripti. node --run pre/post skriptlarini chaqirmaydi.

4.2 Muhit o'zgaruvchilari

bash
node --run salom
npm run salom --silent
text
undefined salom
salom undefined

npm run skriptga npm_lifecycle_event (va boshqa npm_* o'zgaruvchilarni) beradi. node --run esa o'zinikini: NODE_RUN_SCRIPT_NAME va NODE_RUN_PACKAGE_JSON_PATH. Skriptingiz npm_* ga tayansa — node --run bilan ishlamaydi.

Hujjat bo'yicha ikkalasida bir xil: node_modules/.bin PATH'ga qo'shiladi (shuning uchun skriptda tsc deb yoza olasiz). node --run ham package.json ni ota papkalardan qidiradi — biz ichki/ papkasidan chaqirdik, ota papkadagi skript topildi.

Skript yo'q bo'lsa:

text
Missing script: "yoq" for C:\Users\…\r\package.json

Available scripts are:
  prestart: node -e "console.log('prestart ishladi')"
  start: node ism.mjs
  salom: node nomi.mjs

Xabar: "yoq skripti yo'q; mavjudlari: …" — exit 1.

Yana bitta tuzoq. .env ni --run bilan birga bersangiz-chi? .env da SIR=bor, skript esa process.env.SIR ni chiqaradi:

bash
node --env-file=.env --run sir
text
undefined

Hujjatda ham shunday yozilgan: --env-file dan yuklangan o'zgaruvchilar --run bajargan buyruqqa o'tmaydi. Bayroq skriptning o'ziga yoziladi — kanondagi start aynan shunday: node --env-file-if-exists=.env src/bin.ts.

4.3 Qancha tezroq?

Kanon o'lchovi: valyuta kurs USD (tarmoqsiz) to'rt xil usulda, har biri 15 marta, aralash tartibda, bitta seansda:

valyuta kurs USD: sovuq ishga tushish (mediana, 15 marta)
  • node dist/bin.jstayyor JS103,5 ms
  • node src/bin.tstype stripping164,5 ms
  • node --run start.ts + skript265,6 ms
  • npm run start.ts + npm458,6 ms

Manba: O'lchandi: valyuta holat 41, Node 24.21.0, npm 11.19.0, Windows 11, i5-12500H, 2026-10-23

Grafikda uchinchi va to'rtinchi ustunga qarang. Ikkalasi bir xil node src/bin.ts ni bajaradi. Farq faqat ishga tushiruvchida. Masalan, npm run qo'shimcha ~190 ms oladi — npm'ning o'zi yuklanadi, sozlamalarni o'qiydi. Lekin node --run ham node src/bin.ts dan ~100 ms sekin. Sababi: Node ikki marta ishga tushadi: avval --run ni bajaruvchi jarayon, keyin skriptdagi node. Ikkinchi ustun bilan farqi — keyingi darsda.

Sizda raqamlar boshqacha chiqadi — mashina va yukka bog'liq. Nisbat esa saqlanadi.

Maslahat: Kuniga ko'p ishlatiladigan buyruqlar (test, start) uchun node --run qulay. npm publish oldidan avtomatik ishlaydigan prepack kabi hayot sikli skriptlari esa faqat npm orqali ishlaydi — ularga tegmang.

5. nodemon va dotenv qachon hali kerak?

O'rnatmasdan, hujjat va versiyalar bo'yicha (2026-10-23 holatiga: nodemon 3.1.14, dotenv 18.0.9):

Ehtiyoj Node 24 Paket
Kod o'zgarsa qayta ishga tushirish --watch yetadi —
.json, .sql kabi import qilinmagan fayllar --watch-path (papka bilan) nodemon: --ext, --ignore naqshlari
Node bo'lmagan buyruqni qayta ishga tushirish (python, go run) yo'q nodemon --exec
Qayta ishga tushirishdan oldin kechikish yo'q nodemon --delay
.env o'qish --env-file, loadEnvFile —
${BOSHQA} kabi o'zgaruvchi ichida o'zgaruvchi yo'q dotenv-expand
Shifrlangan .env yo'q dotenv'ning pullik ekotizimi va boshqalar
Node 18 kabi eski versiyani qo'llash bayroqlar yo'q ikkalasi ham ishlaydi

Xulosa: yangi loyihada avval Node'ning o'zini ishlating. Paketni aniq ehtiyoj paydo bo'lganda qo'shing. Eski loyihada nodemon va dotenv ni ko'p uchratasiz — ular ishlaydi, shoshib olib tashlash shart emas.

6. CLI qadami: dev va start skriptlari (holat 41, 1-qism)

Holat 41 ikki darsdan iborat: bugun skriptlar va .env, keyingi darsda — TypeScript'ni to'g'ridan ishga tushirish. Hali commit qilmang — commit keyingi darsda.

package.json dagi o'zgarish (kanon):

diff
   "scripts": {
-    "start": "node src/bin.ts",
+    "dev": "node --watch --env-file-if-exists=.env src/bin.ts",
+    "start": "node --env-file-if-exists=.env src/bin.ts",
     "build": "tsc -p tsconfig.build.json",

Yangi fayl .env.example — namuna, git'ga tushadi:

text
# valyuta uchun lokal sozlamalar — nusxa oling: .env (git'ga qo'shilmaydi)
# VALYUTA_API=https://cbu.uz/uz/arkhiv-kursov-valyut/json/
# VALYUTA_KUTISH=5000
# VALYUTA_OFFLINE=1

.gitignore ga bitta qator: .env. Haqiqiy .env — sizning kompyuteringizniki.

Nega --env-file emas, --env-file-if-exists? Repozitoriyni yangi klon qilgan odamda .env yo'q. --env-file bilan npm start darhol not found va exit 9 bilan yiqilardi. valyuta ga esa .env shart emas — sukut qiymatlar bor.

Tekshiruv — biz .env.example dan .env yasab, VALYUTA_OFFLINE=1 qatorining izohini olib tashladik:

bash
cp .env.example .env
node --run start -- kurs USD
text
Ogohlantirish: offline rejim — saqlangan namuna kurslar (fixtures/) ishlatildi
2026-10-23 holatiga (fixture)
USD    1    11 903.15   -62.36  AQSH dollari

(fixture) — .env dagi VALYUTA_OFFLINE=1 o'qildi. .env ni o'chirib qayta ishga tushirdik:

text
.env not found. Continuing without it.
2026-10-23 holatiga (api)
USD    1    11 903.15   -62.36  AQSH dollari

Birinchi qator — --env-file-if-exists ning stderr'dagi xabari. Endi kurs haqiqiy CBU API'dan keldi ((api)).

npm run dev — kuzatish rejimi. src/ dagi har .ts fayl bin.ts dan import daraxti orqali bog'langan, shuning uchun --watch-path kerak emas. .env o'zgarsa ham qayta ishga tushadi — biz sinadik: --watch --env-file=.env bilan .env ni o'zgartirganda Restarting chiqdi va yangi qiymat ko'rindi.

7. Ko'p uchraydigan xatolar

Belgi Sabab Davosi
node: .env: not found, exit 9 --env-file fayl majburiy --env-file-if-exists yoki faylni yarating
.env dagi qiymat ishlamayapti Terminalda shu nom bilan o'zgaruvchi bor — u ustun echo $VALYUTA_KUTISH bilan tekshiring
Number(process.env.X) — 0 .env da X= bo'sh env.X || undefined, keyin tekshiruv
--watch JSON o'zgarishini ko'rmadi Fayl import qilinmagan --watch-path (va src ni ham)
node --run build dan keyin prebuild ishlamadi node --run pre/post ni chaqirmaydi Bitta skriptga birlashtiring yoki npm run
node --env-file=.env --run start — qiymat yo'q --env-file --run skriptiga o'tmaydi Bayroqni skriptning ichiga yozing
Skript npm_package_version ni o'qiy olmadi node --run npm_* bermaydi Versiyani package.json dan o'qing
.env git'ga tushib qoldi .gitignore da yo'q edi .gitignore ga qo'shing; sir bo'lsa — yangisini yarating

8. Mashqlar

Yechimlar kurs/mashqlar/24/40-watch-env-run/ da.

1-mashq (oson): bayroqlar

  • .env bo'lmasa ham dasturni ishga tushiradigan bayroq — --env-file-
  • Haqiqiy muhit va .env da bir xil kalit — ustun turadi:
  • node --run test pretest ni chaqiradimi?
  • --watch faqat import daraxtini kuzatadi; boshqa papka uchun — --
  • .env dagi X= — process.env.X qiymati:
Yechim
  • if-exists — fayl yo'q bo'lsa stderr'ga xabar yozadi va davom etadi.
  • muhit — terminal/tizim bergan qiymat fayldan ustun.
  • yo'q — pre/post skriptlari faqat npm run da.
  • watch-path — bu bayroq bo'lsa import daraxti kuzatilmaydi.
  • bo'sh satr — "", undefined emas.

2-mashq (o'rta): sozlamani tekshirib o'qish

.env matnidan valyuta sozlamasini yasaydigan readSettings(text) funksiyasini yozing (util.parseEnv bilan). Natija { offline, timeoutMs }: VALYUTA_OFFLINE faqat "1" bo'lsa true; VALYUTA_KUTISH berilmagan yoki bo'sh bo'lsa — 5000, aks holda musbat butun son bo'lishi shart, bo'lmasa Error tashlansin: VALYUTA_KUTISH musbat butun son bo'lsin: "<qiymat>". Uch holatni sinang: bo'sh matn, VALYUTA_OFFLINE=1 + VALYUTA_KUTISH= va VALYUTA_KUTISH=tez.

Yechim
js
import { parseEnv } from "node:util";

function readSettings(text) {
  const env = parseEnv(text);
  const raw = env.VALYUTA_KUTISH || undefined; // "" ham berilmagan
  const timeoutMs = raw === undefined ? 5000 : Number(raw);
  if (!Number.isInteger(timeoutMs) || timeoutMs <= 0) {
    throw new Error(
      `VALYUTA_KUTISH musbat butun son bo'lsin: "${raw}"`,
    );
  }
  return { offline: env.VALYUTA_OFFLINE === "1", timeoutMs };
}

console.log(readSettings(""));
console.log(readSettings("VALYUTA_OFFLINE=1\nVALYUTA_KUTISH="));
try {
  readSettings("VALYUTA_KUTISH=tez");
} catch (error) {
  console.log(error.message);
}

Konsolda:

text
{ offline: false, timeoutMs: 5000 }
{ offline: true, timeoutMs: 5000 }
VALYUTA_KUTISH musbat butun son bo'lsin: "tez"

Ikkinchi holat — asosiy tuzoq: VALYUTA_KUTISH= bo'sh satr beradi, || undefined bo'lmasa Number("") → 0 va tekshiruv "0 musbat emas" deb yiqilardi.

3-mashq (qiyin): npm run va node --run nima bajaradi?

plan(scripts, name, runner) funksiyasini yozing. U bajariladigan buyruqlar ro'yxatini qaytarsin: runner === "npm" bo'lsa — pre<name>, <name>, post<name> (bor bo'lganlari); "node" bo'lsa — faqat <name>. Skript yo'q bo'lsa — Error tashlansin: Missing script: "<name>" va keyingi qatorda Available: <nomlar vergul bilan>. Bu toza JS — saytdagi «Ishga tushir» bilan sinashingiz mumkin.

Yechim
js
function plan(scripts, name, runner) {
  if (!(name in scripts)) {
    const names = Object.keys(scripts).join(", ");
    throw new Error(`Missing script: "${name}"\nAvailable: ${names}`);
  }
  const order =
    runner === "npm" ? [`pre${name}`, name, `post${name}`] : [name];
  return order.filter((n) => n in scripts).map((n) => scripts[n]);
}

const scripts = {
  pretest: "npm run tip",
  test: 'node --test "test/**/*.test.ts"',
  posttest: "echo tayyor",
};
console.log(plan(scripts, "test", "npm"));
console.log(plan(scripts, "test", "node"));
try {
  plan(scripts, "start", "node");
} catch (error) {
  console.log(error.message);
}

Konsolda:

text
[ 'npm run tip', 'node --test "test/**/*.test.ts"', 'echo tayyor' ]
[ 'node --test "test/**/*.test.ts"' ]
Missing script: "start"
Available: pretest, test, posttest

Bu farq real loyihada sezilmay qoladi: pretest da tip tekshiruvi bo'lsa, node --run test uni jim o'tkazib yuboradi. Shuning uchun kanonda check skripti hammasini aniq ketma-ket yozadi (npm run tip && npm run lint && npm test).

4-mashq: CLI qadami

valyuta ga dev va start skriptlarini (--watch, --env-file-if-exists), .env.example ni qo'shing, .gitignore ga .env ni yozing. Tekshiring: (1) .env siz node --run start -- kurs USD — not found. Continuing without it. va kurs; (2) .env da VALYUTA_OFFLINE=1 bilan — (fixture); (3) npm run dev ishlab turganda src/kurs.ts ni saqlang — Restarting chiqsin. Commit qilmang.

Yechim

Namuna — «CLI qadami» bo'limidagi diff va .env.example. git status da .env ko'rinmasligi kerak (u .gitignore da), .env.example esa yangi fayl sifatida ko'rinadi. npm run dev ni Ctrl+C bilan to'xtatasiz.

9. Real ishda

  • Backend loyihalar (Express, Fastify, NestJS — 25-qismdan) dev rejimida aynan shunday ishga tushiriladi: node --watch --env-file=.env src/server.ts. Eski loyihalarda o'rnida nodemon + dotenv turadi.
  • Docker va serverlarda .env fayli umuman bo'lmasligi mumkin — qiymatlar platforma panelidan muhit o'zgaruvchisi bo'lib keladi. "Haqiqiy muhit ustun" qoidasi shuning uchun muhim.
  • CI'da node --run test vaqt tejaydi: har ishga tushishda ~0.2 s, katta monorepoda yuzlab marta.
  • Intervyu savollari: "nodemon'siz kodni qanday qayta ishga tushirasiz?", ".env va haqiqiy env'dan qaysi ustun?", "node --run va npm run farqi?".

Xulosa

  • node --watch kirish fayli va import daraxtini kuzatadi; boshqa fayllar uchun --watch-path (unda import daraxti kuzatilmaydi).
  • --env-file fayl majburiy (yo'q bo'lsa exit 9), --env-file-if-exists — ixtiyoriy; haqiqiy muhit .env dan ustun, keyingi --env-file oldingisidan.
  • process.loadEnvFile() koddan yuklaydi va ENOENT tashlaydi; util.parseEnv — formatni tushunish uchun (bo'sh qiymat "").
  • node --run npm'siz ishlaydi: valyuta da 266 ms vs 459 ms, lekin pre/post va npm_* o'zgaruvchilari yo'q.
  • nodemon va dotenv — faqat Node bermaydigan imkoniyat kerak bo'lganda.

Keyingi dars: TypeScript'ni Node'da to'g'ridan ishga tushirish — node src/bin.ts ichida nima bo'ladi, nega u dist/bin.js dan 61 ms sekin va qaysi TS sintaksisi ishlamaydi.

Manbalar

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Node.js --watch, --env-file va node --run: nodemon va dotenv'siz ishlab chiqish — IlmHamroh