İçeriğe geç
DevOps

npm Package Yönetimi: Bağımlılık ve Versiyon Kontrolü

Tarık Tunç
npm Package Yönetimi: Bağımlılık ve Versiyon Kontrolü

npm Package Yönetimi: Bağımlılık ve Versiyon Kontrolü

Node.js ekosisteminin kalbi olan npm (Node Package Manager), milyonlarca paketi barındıran dünyanın en büyük yazılım kayıt defterini yönetir. Ancak bağımlılık yönetimi sadece npm install çalıştırmaktan ibaret değildir. Versiyon çakışmaları, güvenlik açıkları, package-lock.json yönetimi ve performans optimizasyonu gibi konuları anlamak, sağlıklı bir proje sürdürmenin anahtarıdır. Bu rehberde npm'in ileri seviye özelliklerini, bağımlılık stratejilerini ve en iyi pratikleri detaylı olarak inceliyoruz.

Semantic Versioning (SemVer) Sistemi

npm paketleri Semantic Versioning standardını kullanır. Bu sistemi anlamak, bağımlılık yönetiminin temelidir:

# Versiyon formatı: MAJOR.MINOR.PATCH
# Örnek: 4.18.2

# MAJOR (4.x.x): Geriye uyumsuz değişiklikler (breaking changes)
# MINOR (x.18.x): Geriye uyumlu yeni özellikler
# PATCH (x.x.2): Geriye uyumlu bug fix'ler

# package.json'daki versiyon operatörleri:
{
  "dependencies": {
    "react": "^18.2.0",    // ^: MAJOR sabit, MINOR ve PATCH güncellenir (18.x.x)
    "lodash": "~4.17.21",  // ~: MAJOR ve MINOR sabit, sadece PATCH güncellenir (4.17.x)
    "express": "4.18.2",   // Tam versiyon: Sadece bu versiyon yüklenir
    "next": ">=14.0.0",    // Bu versiyon ve üstü
    "typescript": "*"      // Herhangi bir versiyon (önerilmez)
  }
}
Uyarı: ^ (caret) operatörü npm'in varsayılanıdır ve genellikle güvenlidir. Ancak bazı paketler MINOR güncellemelerde breaking change yapabilir. Production uygulamalarında package-lock.json dosyasını mutlaka versiyon kontrolüne dahil edin ve CI'da npm ci kullanın.

package.json ve package-lock.json

Bu iki dosya arasındaki farkı anlamak kritik öneme sahiptir:

// package.json - Bağımlılık aralıklarını tanımlar
{
  "name": "my-project",
  "version": "1.0.0",
  "dependencies": {
    "react": "^18.2.0"      // 18.2.0 - 18.x.x arası
  },
  "devDependencies": {
    "typescript": "^5.3.0"   // 5.3.0 - 5.x.x arası
  },
  "peerDependencies": {
    "react": ">=18.0.0"      // Bu paketin çalışması için React 18+ gerekli
  },
  "optionalDependencies": {
    "fsevents": "^2.3.0"     // Yüklenemezse hata vermez (macOS specific)
  },
  "engines": {
    "node": ">=18.0.0",
    "npm": ">=9.0.0"
  }
}

// package-lock.json - Tam versiyon ağacını kilitler
// Bu dosyayı ASLA manuel düzenlemeyin
// Her zaman versiyon kontrolüne dahil edin

Temel npm Komutları

# Paket yükleme
npm install express                # dependencies'e ekle
npm install -D jest                # devDependencies'e ekle
npm install --save-exact react     # Tam versiyon ile kaydet (^ olmadan)

# Global paket yönetimi
npm install -g vercel              # Global yükleme
npm list -g --depth=0              # Global paketleri listele
npm uninstall -g create-react-app  # Global paketi kaldır

# Bağımlılık bilgileri
npm list                           # Bağımlılık ağacını görüntüle
npm list --depth=0                 # Sadece direkt bağımlılıkları göster
npm outdated                       # Güncel olmayan paketleri listele
npm view react versions           # Paketin tüm versiyonlarını görüntüle
npm info express                   # Paket detay bilgileri

# Güncelleme
npm update                         # Tüm paketleri güncelle (SemVer'e uygun)
npm update lodash                  # Belirli bir paketi güncelle

# Temizlik
npm prune                          # Kullanılmayan paketleri kaldır
npm cache clean --force            # npm cache'ini temizle

npm ci vs npm install

CI/CD ortamlarında doğru komutu kullanmak önemlidir:

# npm install
# - package-lock.json'u GÜNCELLEYEBİLİR
# - Mevcut node_modules'u korur
# - Geliştirme ortamında kullanın

# npm ci (Clean Install)
# - package-lock.json'u DEĞİŞTİRMEZ
# - node_modules'u SİLİP sıfırdan oluşturur
# - package-lock.json ile package.json uyumsuzsa HATA verir
# - CI/CD ortamlarında kullanın
# - Daha hızlı ve daha güvenilir

# CI pipeline örneği
npm ci --ignore-scripts  # Post-install script'lerini atla (güvenlik)
npm ci --only=production # Sadece production bağımlılıkları
İpucu: npm ci her zaman node_modules klasörünü sıfırdan oluşturur, bu yüzden "bende çalışıyor" sorunlarını önler. CI/CD pipeline'larınızda mutlaka npm ci kullanın.

Güvenlik Denetimi

Bağımlılıklarınızdaki güvenlik açıklarını düzenli olarak kontrol edin:

# Güvenlik taraması
npm audit

# Detaylı rapor
npm audit --json

# Otomatik düzeltme
npm audit fix

# Breaking change içeren düzeltmeler dahil
npm audit fix --force  # DİKKAT: Major version güncellemesi yapabilir

# Belirli seviyedeki açıkları filtrele
npm audit --audit-level=high

# CI'da güvenlik kontrolü (high ve critical açıklarda başarısız olur)
npm audit --audit-level=high
Uyarı: npm audit fix --force komutu major version güncellemeleri yapabilir ve breaking change'lere yol açabilir. Bu komutu kullanmadan önce npm audit çıktısını inceleyip, güncelemelerin etkisini değerlendirin.

Workspaces ile Monorepo Yönetimi

npm workspaces, tek bir repository'de birden fazla paketi yönetmenizi sağlar:

// package.json (root)
{
  "name": "my-monorepo",
  "private": true,
  "workspaces": [
    "packages/*",
    "apps/*"
  ]
}

// Proje yapısı:
// my-monorepo/
// ├── package.json
// ├── packages/
// │   ├── ui/package.json
// │   └── utils/package.json
// └── apps/
//     ├── web/package.json
//     └── mobile/package.json
# Workspace komutları
npm install                              # Tüm workspace'lerin bağımlılıklarını yükle
npm run build -w packages/ui             # Belirli workspace'te komut çalıştır
npm run test --workspaces                # Tüm workspace'lerde test çalıştır
npm install lodash -w apps/web           # Belirli workspace'e paket ekle

npx ve Paket Çalıştırma

# npx: Paketleri yüklemeden çalıştır
npx create-next-app@latest my-app
npx eslint --init
npx prettier --write .

# npm exec (npm 7+)
npm exec -- eslint .

# package.json script'leri
{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "eslint .",
    "preinstall": "npx only-allow npm",  # Sadece npm kullanımını zorla
    "prepare": "husky install"            # npm install sonrası otomatik çalışır
  }
}

npm Alternatifleri Karşılaştırması

Özellik npm yarn pnpm
Disk Kullanımı Yüksek (flat) Yüksek (flat) Düşük (hardlinks)
Kurulum Hızı Orta Hızlı En hızlı
Monorepo Desteği Workspaces Workspaces Workspaces + strict
Phantom Dependencies Mümkün Mümkün Engellenir
Bilgi: pnpm, aynı paketin farklı versiyonlarını hardlink'ler aracılığıyla tek bir yerde saklar. Bu, disk kullanımını önemli ölçüde azaltır ve yükleme süresini hızlandırır. Monorepo projelerinde pnpm özellikle avantajlıdır.

Best Practices

  • package-lock.json'u commit edin: Tüm ortamlarda aynı bağımlılıkların yüklenmesini garanti eder
  • engines alanını tanımlayın: Node.js ve npm versiyon gereksinimlerini belirtin
  • Düzenli güncelleme yapın: npm outdated ile güncel olmayan paketleri kontrol edin
  • Güvenlik taraması yapın: CI'da npm audit çalıştırın
  • Gereksiz bağımlılıklardan kaçının: Her eklediğiniz paket potansiyel bir risk ve bakım yüküdür
  • .npmrc ile yapılandırma yapın: Registry, save-exact gibi ayarları proje bazında tanımlayın

Sonuç

npm, JavaScript ekosisteminin bağımlılık yönetim merkezidir. Semantic versioning'i anlamak, package-lock.json'u doğru yönetmek, güvenlik taramalarını düzenli yapmak ve CI/CD'de doğru komutları kullanmak, sağlıklı bir proje sürdürmenin temelini oluşturur. Bu rehberdeki pratikleri uygulayarak bağımlılık yönetimi konusunda profesyonel bir yaklaşım geliştirebilirsiniz.

Kaynaklar

İlgili Yazılar