Environment Variables — dotenv, process.env, konfiguratsiya
Muammodan boshlaylik
Yangi dasturchining kodida ko'pincha shunday qatorlar ko'rinadi:
const db = mongoose.connect('mongodb://admin:parol123@localhost:27017/myapp');
const jwtSecret = 'mening-maxfiy-kalitim';
const apiKey = 'sk-live-abc123xyz789';
Kod GitHub ga push qilindi. Ertasi kuni ma'lumotlar bazasi buzib kirildi, API hisob o'chirildi, JWT tokenlar soxtalashtirildi.
Bu — hardcoded credentials muammosi. Maxfiy ma'lumotlar hech qachon kodda yozilmaydi. Environment variables aynan shu uchun.
Environment variable nima?
Environment variable — operatsion tizim darajasida saqlanadigan kalit-qiymat juftligi. Dastur ishga tushganda ularni o'qiydi. Kod ichida yozilmaydi — har bir muhitda (local, staging, production) alohida belgilanadi.
Hayotiy o'xshatma: restoran oshpazi retseptni biladi, lekin maxsus ziravorlarni ombor xonasida saqlaydi — retseptda "ombordan ol" deb yozilgan, ziravorning o'zi retseptda ko'rsatilmaydi. Environment variable ham shunday: kod "muhitdan ol" deydi, qiymat esa tashqarida.
process.env — o'rnatilgan mexanizm
Node.js da environment variable lar process.env orqali o'qiladi:
console.log(process.env.HOME); // /home/jasur
console.log(process.env.PATH); // /usr/local/bin:/usr/bin:...
console.log(process.env.NODE_ENV); // "development" yoki "production"
O'zingizning o'zgaruvchilaringizni terminal orqali berish:
# Linux/Mac
DB_URL=mongodb://localhost:27017 PORT=4000 node server.js
# Windows PowerShell
$env:DB_URL="mongodb://localhost:27017"; $env:PORT="4000"; node server.js
// server.js
const port = process.env.PORT || 3000;
const dbUrl = process.env.DB_URL;
console.log(`Port: ${port}`);
console.log(`DB: ${dbUrl}`);
|| 3000 — muhitda PORT berilmagan bo'lsa, standart qiymat ishlaydi.
dotenv — .env fayl
Har safar terminaldi o'zgaruvchilar yozish noqulay. dotenv kutubxonasi .env faylidagi o'zgaruvchilarni avtomatik process.env ga yuklaydi.
npm install dotenv
# .env fayl — loyiha ildizida
PORT=3000
NODE_ENV=development
DB_HOST=localhost
DB_PORT=5432
DB_NAME=myapp
DB_USER=postgres
DB_PASS=secret123
JWT_SECRET=juda-uzun-va-tasodifiy-satr-kamida-32-belgi
JWT_EXPIRES_IN=7d
REDIS_URL=redis://localhost:6379
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=noreply@myapp.uz
SMTP_PASS=app-password-here
// server.js — eng birinchi qatorda yuklash
require('dotenv').config();
// Endi process.env da mavjud
const port = process.env.PORT || 3000;
const dbHost = process.env.DB_HOST;
const jwtSecret = process.env.JWT_SECRET;
Nima uchun eng boshida? dotenv.config() chaqirilgunga qadar process.env da ular yo'q. Boshqa modullar import qilinishidan oldin yuklash kerak.
.gitignore — asosiy qoida
.env fayli hech qachon git ga qo'shilmaydi:
# .gitignore
.env
.env.local
.env.production
O'rniga .env.example fayli yaratiladi — qiymatlar bo'sh, faqat qaysi o'zgaruvchilar kerakligi ko'rsatiladi:
# .env.example — git ga qo'shiladi, komandaga ko'rsatish uchun
PORT=
NODE_ENV=
DB_HOST=
DB_PORT=
DB_NAME=
DB_USER=
DB_PASS=
JWT_SECRET=
JWT_EXPIRES_IN=
REDIS_URL=
SMTP_HOST=
SMTP_PORT=
SMTP_USER=
SMTP_PASS=
Yangi dasturchi loyihaga qo'shilganda: .env.example ni ko'chirib .env yaratadi, qiymatlarni to'ldiradi.
Konfiguratsiya moduli — yaxshi pattern
process.env ni hamma joydan to'g'ridan-to'g'ri o'qish yomon amaliyot — qiymat yo'q bo'lsa dastur o'rta joyda xato beradi. Yaxshisi barcha konfiguratsiyani bir joyda yig'ib, tekshirib, export qilish:
// src/config/index.js
require('dotenv').config();
function talab(nomi) {
const qiymat = process.env[nomi];
if (!qiymat) {
throw new Error(`Muhit o'zgaruvchisi topilmadi: ${nomi}`);
}
return qiymat;
}
function ixtiyoriy(nomi, standart) {
return process.env[nomi] || standart;
}
module.exports = {
port: ixtiyoriy('PORT', '3000'),
nodeEnv: ixtiyoriy('NODE_ENV', 'development'),
db: {
host: talab('DB_HOST'),
port: ixtiyoriy('DB_PORT', '5432'),
name: talab('DB_NAME'),
user: talab('DB_USER'),
pass: talab('DB_PASS'),
},
jwt: {
secret: talab('JWT_SECRET'),
expiresIn: ixtiyoriy('JWT_EXPIRES_IN', '7d'),
},
smtp: {
host: talab('SMTP_HOST'),
port: ixtiyoriy('SMTP_PORT', '587'),
user: talab('SMTP_USER'),
pass: talab('SMTP_PASS'),
},
isProd: process.env.NODE_ENV === 'production',
isDev: process.env.NODE_ENV === 'development',
};
// server.js
const config = require('./src/config');
app.listen(config.port, () => {
console.log(`Server: http://localhost:${config.port}`);
console.log(`Muhit: ${config.nodeEnv}`);
});
// db.js
const config = require('./src/config');
const pool = new Pool({
host: config.db.host,
port: config.db.port,
database: config.db.name,
user: config.db.user,
password: config.db.pass,
});
Nima uchun bu yaxshi? Server ishga tushishi bilan barcha talab qilingan o'zgaruvchilar tekshiriladi. Biror biri yo'q bo'lsa — darhol aniq xato xabari, emas biror joyda undefined muammosi.
NODE_ENV — muhitni belgilash
NODE_ENV — qaysi muhitda ishlayotganini bildiradi. Dasturning xulqi shunga qarab o'zgaradi:
const config = require('./config');
// Xatolar faqat devda batafsil
app.use((err, req, res, next) => {
if (config.isDev) {
res.json({ error: err.message, stack: err.stack });
} else {
res.json({ error: 'Ichki xato' }); // produksiyada stack ko'rsatilmaydi
}
});
// Log darajasi
const logDarajasi = config.isProd ? 'error' : 'debug';
NODE_ENV uchta standart qiymat oladi: development, production, test.
Produksiyada environment variables
Produksiyada .env fayli serverga ko'chirilmaydi — o'zgaruvchilar platformada to'g'ridan-to'g'ri belgilanadi:
VPS (Linux):
# /etc/environment yoki systemd service faylida
Environment="PORT=3000"
Environment="DB_PASS=super-secret"
Vercel, Render, Railway: Dashboard → Settings → Environment Variables → Kalit va qiymat qo'shiladi.
Docker:
docker run -e PORT=3000 -e DB_PASS=secret myapp
# docker-compose.yml
services:
app:
image: myapp
environment:
- PORT=3000
- DB_PASS=secret
# yoki fayldan
env_file:
- .env.production
Tez-tez uchraydigan xatolar
Qayta ishga tushirmay kutish
// .env ga qiymat qo'shdingiz — lekin server hali eski holat bilan ishlayapti
// ✅ Serverni qayta ishga tushiring
Raqam sifatida o'qish
// process.env dan kelgan barcha qiymatlar — STRING
const port = process.env.PORT;
typeof port; // "string", "number" emas!
// ✅ Raqamga aylantirish kerak bo'lsa
const port = Number(process.env.PORT) || 3000;
// yoki
const port = parseInt(process.env.PORT, 10) || 3000;
Boolean qiymat
// ❌ Bu har doim true — "false" ham truthy string
const debugMode = process.env.DEBUG_MODE;
if (debugMode) { ... }
// ✅ String bilan taqqoslash
const debugMode = process.env.DEBUG_MODE === 'true';
.env faylini git ga push qilish
# Git ga qo'shib yuborgan bo'lsangiz — tarixdan ham o'chirish kerak
git rm --cached .env
git commit -m "env faylini tarixdan o'chirish"
# Va barcha maxfiy kalitlarni almashtirishni unutmang!
Xulosa
Environment variables — maxfiy ma'lumotlarni koddan ajratishning standart usuli. Bu professional dasturlashning asosiy qoidalaridan biri.
Eslab qoling:
- Maxfiy ma'lumotlar hech qachon kodda yozilmaydi
dotenv—.envfayliniprocess.envga yuklaydi.env—.gitignoreda,.env.example— gitdaprocess.envdan kelgan barcha qiymatlar string- Konfiguratsiya modulida talab qilingan o'zgaruvchilar tekshiriladi
NODE_ENV—development,production,test- Produksiyada hosting platformasi dashboard da belgilanadi
Node.js kursi tugallandi. Tabriklaymiz!
Siz Node.js ning asosi — Event Loop, Core modullar, Stream, Process, va amaliy vositalarni o'rgandingiz. Endi Express yoki NestJS bilan real API yaratishga tayyorsiz.