[NODE JS] dotenv ile Konfigürasyon Yönetimi
Merhaba arkadaşlar, bir önceki konuda environment variable'ların ne olduğunu anlatmıştım. Şimdi pratikte en çok kullanılan dotenv paketini detaylıca ele alacağız. dotenv, .env dosyasındaki key-value çiftlerini process.env'e yükler ve kullanıma hazır hale getirir.
dotenv Node.js ekosisteminin en popüler paketlerinden biri, haftalık 40 milyondan fazla indirmesi var. Sıfır bağımlılık, sıfır konfigürasyon, sadece yap ve kullan mantığıyla çalışır. Projenizin kök dizinine bir .env dosyası koyarsınız, uygulamanızın en başında require('dotenv').config() çağırırsınız, bitir. Tüm değişkenler process.env üzerinden erişilebilir olur.
Ama dotenv'in bazı incelikleri var. Mesela hangi sırayla yüklenir, var olan değişkenlerin üzerine yazar mı, birden fazla .env dosyası nasıl yönetilir, production'da nasıl davranır... Bu detayları bilmezseniz beklenmedik davranışlarla karşılaşırsınız.
Ben projelerimde genelde şöyle bir yapı kurarım: .env.development, .env.test, .env.production dosyaları oluştururum. NODE_ENV'e göre doğru dosyayı yükleyen bir config modülü yazarım. Bu şekilde her ortamın konfigürasyonu ayrı ayrı yönetilir ve karışma riski olmaz.
Temel Kullanım
JavaScript:
// Kurulum: npm install dotenv
// En basit kullanim - uygulamanin en basinda
require('dotenv').config();
// Artik .env dosyasindaki tum degiskenler process.env'de
console.log(process.env.DB_HOST);
console.log(process.env.API_KEY);
// Farkli dosya yuklemek
require('dotenv').config({ path: '.env.production' });
// Override: var olan degiskenlerin ustune yazma
require('dotenv').config({ override: true });
// Debug modu: hangi degiskenlerin yuklendigini gor
require('dotenv').config({ debug: true });
// ES Modules ile kullanim
// import 'dotenv/config';
// -----------------------------------------------
// Gelismis config modulu
// -----------------------------------------------
const path = require('path');
const dotenv = require('dotenv');
class Config {
constructor() {
const ortam = process.env.NODE_ENV || 'development';
// Once genel .env dosyasini yukle
dotenv.config({ path: path.resolve(process.cwd(), '.env') });
// Sonra ortama ozel dosyayi yukle (ustune yazar)
const ortamDosyasi = path.resolve(process.cwd(), '.env.' + ortam);
dotenv.config({ path: ortamDosyasi, override: true });
// Lokal override dosyasi (gitignore'da olmali)
const lokalDosya = path.resolve(process.cwd(), '.env.local');
dotenv.config({ path: lokalDosya, override: true });
this.dogrula();
}
get(anahtar, varsayilan = undefined) {
const deger = process.env[anahtar];
if (deger === undefined && varsayilan === undefined) {
throw new Error('Eksik environment variable: ' + anahtar);
}
return deger || varsayilan;
}
getInt(anahtar, varsayilan) {
return parseInt(this.get(anahtar, String(varsayilan)), 10);
}
getBool(anahtar, varsayilan = false) {
const deger = this.get(anahtar, String(varsayilan));
return deger === 'true' || deger === '1';
}
dogrula() {
const zorunlular = ['DB_HOST', 'DB_PASSWORD', 'JWT_SECRET'];
const eksikler = zorunlular.filter(key => !process.env[key]);
if (eksikler.length > 0) {
console.error('\nEksik environment variable\'lar:');
eksikler.forEach(key => console.error(' - ' + key));
console.error('\n.env dosyanizi kontrol edin veya .env.example\'dan kopyalayin.\n');
process.exit(1);
}
}
get db() {
return {
host: this.get('DB_HOST', 'localhost'),
port: this.getInt('DB_PORT', 5432),
name: this.get('DB_NAME', 'myapp'),
user: this.get('DB_USER', 'postgres'),
password: this.get('DB_PASSWORD'),
pool: {
min: this.getInt('DB_POOL_MIN', 2),
max: this.getInt('DB_POOL_MAX', 10)
}
};
}
get jwt() {
return {
secret: this.get('JWT_SECRET'),
expiresIn: this.get('JWT_EXPIRES_IN', '24h'),
refreshExpiresIn: this.get('JWT_REFRESH_EXPIRES_IN', '7d')
};
}
get isProduction() {
return this.get('NODE_ENV', 'development') === 'production';
}
}
module.exports = new Config();
Bu Config class'ı dotenv'in üzerine tip dönüşümü, varsayılan değer ve zorunluluk kontrolü ekliyor. Projenin her yerinde config.db.host gibi kullanabilirsiniz. String'den integer veya boolean'a dönüşümü otomatik yapıyor, hata vermek yerine varsayılan değer döndürüyor.
Kullanım Örneği: Express Uygulaması
JavaScript:
// app.js
const config = require('./config');
const express = require('express');
const mongoose = require('mongoose');
const app = express();
// MongoDB baglantisi
mongoose.connect(
'mongodb://' + config.db.user + ':' + config.db.password + '@' + config.db.host + ':' + config.db.port + '/' + config.db.name
).then(() => {
console.log('MongoDB baglandi');
}).catch(err => {
console.error('MongoDB baglanti hatasi:', err.message);
process.exit(1);
});
// JWT middleware
const jwt = require('jsonwebtoken');
function authMiddleware(req, res, next) {
const token = req.headers.authorization;
if (!token) return res.status(401).json({ hata: 'Token gerekli' });
try {
const decoded = jwt.verify(token.replace('Bearer ', ''), config.jwt.secret);
req.user = decoded;
next();
} catch (e) {
res.status(401).json({ hata: 'Gecersiz token' });
}
}
app.get('/api/profil', authMiddleware, (req, res) => {
res.json({ kullanici: req.user });
});
app.listen(config.getInt('PORT', 3000), () => {
console.log('Ortam:', config.get('NODE_ENV', 'development'));
console.log('Port:', config.getInt('PORT', 3000));
if (!config.isProduction) {
console.log('DB:', config.db.host + ':' + config.db.port);
}
});
Best Practices
dotenv kullanırken dikkat etmeniz gereken şeyler var. .env dosyasını asla git'e commit etmeyin, bunu her seferinde söylüyorum çünkü hala yapan var. .env.example dosyasını oluşturup commit edin ki yeni geliştirici hangi değişkenlere ihtiyaç olduğunu bilsin. Production'da dotenv yerine gerçek environment variable'ları tercih edin, Docker ve Kubernetes ortamlarında .env dosyası kullanmak anti-pattern sayılır.
require('dotenv').config() çağrısını mümkün olan en erken noktada yapın, herhangi bir modül import edilmeden önce. Yoksa bazı modüller environment variable'ları kendi init aşamalarında okumaya çalışır ve undefined bulur.
Kolay gelsin!
Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)
Benzer konular
- Cevaplar
- 9
- Görüntüleme
- 473