nvm ile Çoklu Node.js Sürümü Yönetimi

Bir Node.js geliştiricisi veya sistem yöneticisi olarak çalışıyorsanız, eninde sonunda şu sorunla yüzleşirsiniz: bir proje Node.js 14 isterken diğeri Node.js 20 istiyor. Sisteme global olarak tek bir sürüm kurduğunuzda ya eski projeler patlıyor ya da yeni projeler çalışmıyor. İşte tam bu noktada nvm (Node Version Manager) hayat kurtarıcı oluyor.

Bu yazıda nvm’i sıfırdan kurmanı, farklı projelerde farklı Node.js sürümlerini nasıl kullanacağını ve gerçek dünya senaryolarında işini nasıl kolaylaştıracağını anlatacağım. Hem Linux hem de macOS üzerinde geçerli bilgiler paylaşacağım, Windows kullanıcıları için de ayrı bir bölüm ekledim.

nvm Nedir ve Neden Kullanmalısın?

nvm, tek bir sistemde birden fazla Node.js sürümünü yan yana kurmanı ve aralarında geçiş yapmanı sağlayan bir araç. Sistem paket yöneticisi ile (apt, yum, brew gibi) Node.js kurmaktan temel farkı şu: paket yöneticileri genellikle tek bir sürümü sistem genelinde kurar ve sürüm güncellemeleri bazen bağımlılıkları bozar. nvm ise her sürümü kendi izole ortamında tutar, sudo gerektirmez ve saniyeler içinde sürümler arası geçiş yapabilirsin.

Bunu gerçek bir senaryo üzerinden düşün: Şirkette eski bir e-ticaret projesi var, Node.js 12 üzerinde çalışıyor. Bir yandan da ekip yeni bir microservice geliştiriyor, o proje Node.js 20 kullanıyor. Aynı geliştirme makinesinde her iki projeyle de çalışman gerekiyor. nvm olmadan bu bir kabus; nvm ile ise her dizine girdiğinde otomatik olarak doğru sürüm aktif hale geliyor.

Kurulum

Linux ve macOS’ta nvm Kurulumu

Resmi kurulum yöntemi, bir curl veya wget komutuyla script indirip çalıştırmak:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

Ya da wget tercih ediyorsan:

wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

Script çalıştıktan sonra shell konfigürasyon dosyana (.bashrc, .zshrc veya .profile) şu satırlar otomatik eklenir:

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && . "$NVM_DIR/bash_completion"

Değişikliklerin aktif olması için terminal oturumunu yenile:

source ~/.bashrc
# veya zsh kullanıyorsan
source ~/.zshrc

Kurulumu doğrulamak için:

nvm --version
# Çıktı: 0.39.7

Windows’ta nvm-windows Kurulumu

Orijinal nvm Windows’u desteklemiyor. Windows için nvm-windows adında ayrı ama benzer bir proje var. GitHub’daki nvm-windows reposundan .exe installer’ı indirip çalıştırman yeterli. Komut seti neredeyse birebir aynı, bu yüzden aşağıdaki örneklerin büyük çoğunluğu Windows’ta da geçerli.

Temel Komutlar ve Kullanım

Node.js Sürümü Kurma

Önce mevcut ve kurulu sürümlere bakalım:

# Uzak sunucudaki tüm kullanılabilir sürümleri listele
nvm ls-remote

# Sadece LTS sürümlerini listele (bu daha kullanışlı)
nvm ls-remote --lts

# Sistemde kurulu sürümleri göster
nvm ls

Artık sürüm kurmaya hazırız. En güncel LTS sürümünü kuralım:

# En son LTS sürümünü kur
nvm install --lts

# Belirli bir sürüm kur
nvm install 20.11.0

# Sadece major sürüm belirterek en güncel minor/patch'i kur
nvm install 18

# Sürüm kod adıyla kur (LTS sürümlerinin kod adları var)
nvm install lts/iron

Sürümler Arası Geçiş

# Belirli bir sürüme geç
nvm use 20.11.0

# Kısaca major sürüm numarasıyla da geçebilirsin
nvm use 18

# LTS'e geç
nvm use --lts

# Hangi sürümün aktif olduğunu kontrol et
node --version
nvm current

Varsayılan Sürümü Belirleme

Yeni terminal penceresi açtığında hangi sürümün aktif olacağını default alias’ıyla belirlersin:

# Node.js 20'yi varsayılan yap
nvm alias default 20

# Kontrol et
nvm alias

.nvmrc Dosyası ile Proje Bazlı Sürüm Yönetimi

İşte nvm’in en güçlü özelliği bu. Her projenin kök dizinine .nvmrc adında küçük bir dosya bırakırsın, içine sadece istediğin Node.js sürümünü yazarsın. Proje dizinine girdiğinde nvm use komutunu çalıştırmak yeterli, nvm bu dosyayı okuyup doğru sürümü aktif eder.

Önce dosyayı oluşturalım:

# Proje dizinine gir
cd /home/ahmet/projeler/eski-eticaret

# .nvmrc dosyasını oluştur
echo "14.21.3" > .nvmrc

# Başka bir proje için
cd /home/ahmet/projeler/yeni-microservice
echo "20.11.0" > .nvmrc

Artık proje dizinine girip nvm use dediğinde:

cd /home/ahmet/projeler/eski-eticaret
nvm use
# Çıktı: Found '/home/ahmet/projeler/eski-eticaret/.nvmrc' with version <14.21.3>
# Now using node v14.21.3 (npm v6.14.18)

Otomatik Sürüm Geçişi

nvm use yazmak bile istemiyorsan, shell konfigürasyonuna bir fonksiyon ekleyebilirsin. Bash için .bashrc‘ye şunu ekle:

# Dizin değişince otomatik nvm use çalıştır
cdnvm() {
    command cd "$@" || return $?
    nvm_path="$(nvm_find_up .nvmrc | tr -d 'n')"

    if [[ ! $nvm_path = *[^[:space:]]* ]]; then
        declare default_version
        default_version="$(nvm version default)"
        if [[ $default_version == "N/A" ]]; then
            nvm use default
        elif [[ $(nvm current) != "$default_version" ]]; then
            nvm use default
        fi
    elif [[ -r "$nvm_path/.nvmrc" ]]; then
        declare nvm_version
        nvm_version=$(<"$nvm_path/.nvmrc")

        declare locally_resolved_nvm_version
        locally_resolved_nvm_version="$(nvm ls --no-colors "$nvm_version" | tail -1 | tr -d '->*' | tr -d '[:space:]')"

        if [[ "$locally_resolved_nvm_version" == "N/A" ]]; then
            nvm install "$nvm_version"
        elif [[ $(nvm current) != "$locally_resolved_nvm_version" ]]; then
            nvm use "$nvm_version"
        fi
    fi
}
alias cd='cdnvm'

Bu fonksiyonu ekledikten sonra source ~/.bashrc yap. Artık her cd komutunda otomatik olarak doğru Node.js sürümüne geçiş yapılacak.

Gerçek Dünya Senaryoları

Senaryo 1: CI/CD Pipeline’ında Farklı Ortamlar

Bir DevOps senaryosu düşün: Jenkins veya GitHub Actions’ta birden fazla Node.js sürümüyle test çalıştırmak istiyorsun. nvm bunu çok kolaylaştırıyor.

Bir CI script örneği:

#!/bin/bash
set -e

# nvm'i yükle (CI ortamında genellikle shell source edilmeli)
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"

# Test edilecek sürümler
NODE_VERSIONS=("16" "18" "20")

for VERSION in "${NODE_VERSIONS[@]}"; do
    echo "=========================================="
    echo "Node.js $VERSION ile testler çalıştırılıyor"
    echo "=========================================="
    
    nvm install "$VERSION" --silent
    nvm use "$VERSION"
    
    echo "Aktif sürüm: $(node --version)"
    echo "npm sürümü: $(npm --version)"
    
    npm ci
    npm test
    
    echo "Node.js $VERSION testleri tamamlandı"
done

echo "Tüm sürümlerde testler başarılı!"

Bu script, her Node.js sürümünü sırayla yükler, testleri çalıştırır ve sonucu raporlar. Eski bir kütüphane yazıyorsan bu tür cross-version testler hayat kurtarır.

Senaryo 2: Ekip Standardizasyonu

Büyük bir geliştirme ekibinde çalışıyorsan, herkesin aynı Node.js sürümünü kullanmasını sağlamak önemli. .nvmrc dosyasını Git reposuna commit etmek bu sorunun en temiz çözümü.

Projenin package.json dosyasına da engines alanı ekleyebilirsin:

# Önce .nvmrc oluştur ve commit et
echo "20.11.0" > .nvmrc
git add .nvmrc
git commit -m "chore: Node.js sürümünü .nvmrc ile sabitle"

# package.json'a engines eklemek için
cat package.json | python3 -c "
import json, sys
data = json.load(sys.stdin)
data['engines'] = {'node': '>=20.11.0', 'npm': '>=10.0.0'}
print(json.dumps(data, indent=2, ensure_ascii=False))
" > package.json.tmp && mv package.json.tmp package.json

Yeni bir geliştirici projeyi clone’ladığında yapması gereken tek şey:

git clone https://github.com/sirket/proje.git
cd proje
nvm install    # .nvmrc'yi okuyup gerekli sürümü kurar
nvm use        # O sürümü aktif eder
npm install
npm start

Senaryo 3: Global npm Paketlerini Sürümler Arası Taşıma

Bir sürümden diğerine geçtiğinde global npm paketlerin de gitmez. Neyse ki nvm bunu çözen bir komut sunuyor:

# Mevcut global paketleri gör
nvm exec 18 npm list -g --depth=0

# Yeni sürüm kurarken eski sürümün global paketlerini kopyala
nvm install 20 --reinstall-packages-from=18

# Ya da önce kurdum, sonra aktar
nvm install 20
nvm reinstall-packages 18

Bu özellikle typescript, pm2, nodemon gibi sık kullandığın global araçları kaybetmemek için çok işlevsel.

nvm ile npm ve npx Yönetimi

nvm her Node.js sürümüyle birlikte kendi npm’ini de getirir. Bazen npm sürümünü Node.js sürümünden bağımsız olarak güncellemek istersin:

# Aktif Node.js sürümü için npm'i güncelle
nvm install-latest-npm

# Belirli bir npm sürümü kur
npm install -g [email protected]

# Hangi npm sürümünün kurulu olduğunu kontrol et
npm --version

npx ise npm ile birlikte geliyor, ayrıca bir işlem yapman gerekmiyor. Ama hangi Node.js ortamında çalıştığını bilmek istersen:

nvm current
# Çıktı: v20.11.0

which node
# Çıktı: /home/ahmet/.nvm/versions/node/v20.11.0/bin/node

which npm
# Çıktı: /home/ahmet/.nvm/versions/node/v20.11.0/bin/npm

Disk Alanı Yönetimi

Her Node.js sürümü kendi node_modules, binary ve header dosyalarıyla gelir. Zaman içinde eski sürümler disk alanı yemeye başlar. Temizlik yapmak için:

# Kurulu sürümleri listele
nvm ls

# Kullanmadığın eski bir sürümü kaldır
nvm uninstall 14.21.3

# Sisteminizde kaç sürüm kurulu, ne kadar yer kaplıyor
du -sh ~/.nvm/versions/node/*

Tipik bir çıktı şuna benzer:

245M    /home/ahmet/.nvm/versions/node/v16.20.2
251M    /home/ahmet/.nvm/versions/node/v18.19.0
258M    /home/ahmet/.nvm/versions/node/v20.11.0

Her sürüm 250 MB civarında yer kaplıyor. 5-6 eski sürüm birikiyor mu, disk alanını fark eder hale geliyor.

Alias Yönetimi

nvm’in alias sistemi, sürümlere anlamlı isimler verip bu isimlerle kullanmana olanak tanıyor:

# Alias oluştur
nvm alias production 20.11.0
nvm alias staging 18.19.0
nvm alias legacy 14.21.3

# Alias ile geçiş yap
nvm use production
nvm use staging

# Tüm alias'ları gör
nvm alias

# Alias sil
nvm unalias legacy

Bu özellikle birden fazla ortamı (prod, staging, dev) taklit etmen gerektiğinde oldukça faydalı. Bir shell script içinde nvm use production diyerek hangi sürümün kullanılacağını açıkça ifade etmiş olursun.

Sık Karşılaşılan Sorunlar ve Çözümleri

“nvm: command not found” hatası: Shell konfigürasyon dosyası düzgün yüklenmemiş demektir. source ~/.bashrc veya source ~/.zshrc çalıştır. Eğer hata devam ediyorsa kurulum scriptinin .bashrc‘ye eklediği satırları elle kontrol et.

Yeni terminal açtığında nvm aktif olmuyor: .bashrc yerine .bash_profile veya .profile kullanılıyor olabilir. Hangisinin yüklendiğini anlamak için echo $0 komutunu çalıştır.

SSH bağlantılarında nvm çalışmıyor: SSH non-interactive shell açar ve bazı durumlarda .bashrc yüklenmez. Sunucudaki .bashrc başında şu satırlar varsa interactive shell kontrolü yapıyor demektir:

# Bu satırları bul ve nvm satırlarını bu bloğun dışına taşı
# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

nvm yükleme satırlarını bu bloğun üstüne taşı ya da .bash_profile dosyasına ekle.

Sürüm değişikliği script içinde kalıcı olmuyor: nvm use sadece mevcut shell oturumunu etkiler. Script içinde kullandığında, script bittikten sonra eski sürüme dönülür. Bu aslında doğru davranış; sadece script süresince farklı sürüm kullanmış olursun.

nvm’i Güncel Tutmak

nvm kendini otomatik güncellemiyor. Yeni sürüm çıktığında kurulum scriptini tekrar çalıştırmak yeterli:

# Güncel versiyonu kontrol et (GitHub'da bakabilirsin)
nvm --version

# Yeni sürüm kurulumu için install script'i yeni versiyonla tekrar çalıştır
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

Sonuç

nvm, Node.js ile ciddi şekilde çalışan herkesin araç kutusunda olması gereken bir yardımcı program. Sisteme global Node.js kurmak yerine nvm üzerinden yönetmek, hem geliştirme ortamını daha temiz tutuyor hem de proje arası geçişleri sorunsuz hale getiriyor.

Özellikle .nvmrc dosyasını Git reposuna eklemek alışkanlık haline getir. Bu sayede ekipteki herkes ve CI/CD pipeline’ın aynı sürümü kullanır, “bende çalışıyor ama onun makinesinde çalışmıyor” sorunlarının önemli bir kısmını ortadan kaldırırsın.

Yeni bir Node.js projesi başladığında şu üç adımı rutin hale getir: nvm install --lts, echo "$(node --version | cut -c 2-)" > .nvmrc, git add .nvmrc. Bu küçük alışkanlık ilerleyen dönemlerde sana ve ekibine ciddi zaman kazandıracak.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir