pnpm-lock.yaml, package-lock.json, composer.lock commit’lenir. package.json ve composer.json bir aralık kaydediyor, lock dosyası o aralıktan hangi sürümün gerçekten kurulduğunu kaydediyor. Lock dosyası yoksa build makinesi aralığı kendi başına çözer, siz hiç test etmediğiniz bir sürümü kurmuş olursunuz.
Bu hata gecikmeli patlıyor. Bugün eklenen bir bağımlılık üç hafta sonra, hiç dokunmadığınız bir dosyada prod’da çöküyor.
package.json bir aralık, lock bir sonuç
{
"dependencies": {
"some-package": "^2.4.0"
}
}
^2.4.0 2.x serisinin 2.4.0 ve üstü herhangi bir sürümünü kabul ediyor. Sizin makinenizde 2.4.0 kurulu olabilir, build sunucusunda paket yayıncısı dün 2.9.0ı yayımladıysa oradan o kurulur. package-lock.json bu belirsizliği kaldırıyor, tam olarak hangi sürümün ve hangi bağımlı paketlerin kurulacağını satır satır sabitliyor.
Asıl risk sizin doğrudan bağımlılığınızda bile değil. some-package kendi içinde on tane başka pakete bağlı olabilir, onların her biri de kendi aralığını tanımlıyor. package.json sadece sizin yazdığınız paketleri kapsıyor, lock dosyası bu ağacın tamamını, en alttaki bağımlılığa kadar sabitliyor. Lock olmadan iki geliştiricinin node_modulesu aynı package.jsondan bile farklı çıkabilir.
CI’da --frozen-lockfile
Lock dosyası ile package.json birbirinden uzaklaştıysa (biri commit’lendi, diğeri unutuldu) build makinesinin bunu sessizce çözmesini istemezsiniz. İstediğiniz şey build’in patlaması:
pnpm install --frozen-lockfile
npm tarafında karşılığı npm ci. --frozen-lockfile lock dosyasını package.json ile tutarsız bulursa kurulum yapmadan hata veriyor. Drift böylece prod’da değil, CI’da yakalanıyor.
Composer’da aynı disiplin composer installla geliyor, composer update değil:
composer install --no-dev --optimize-autoloader
composer install composer.locktaki tam sürümleri kuruyor. composer update ise composer.jsondaki aralığı yeniden çözüyor, tam da CI’da olmasını istemediğiniz şey.
Docker’da lock’u kaynak koddan önce kopyalayın
COPY pnpm-lock.yaml package.json ./
RUN pnpm install --frozen-lockfile
COPY . .
Lock dosyası değişmediği sürece bu katman Docker’ın kendi cache’inden geliyor, pnpm install tekrar çalışmıyor. Kaynak kodu lock’tan önce kopyalarsanız her kod değişikliği bu katmanı da geçersiz kılar, bağımlılık hiç değişmese bile her build’de yeniden kurulur. Docker imajının 1,2 GB’a çıkma sebebi de büyük ölçüde katman sırasıyla ilgili, ikisi aynı prensibe dayanıyor.
Tek istisna: yayımlanan kütüphane
npm paketi ya da Composer paketi olarak yayımlanan bir kütüphane package-lock.json ya da composer.lock commit’lemez. Kütüphaneyi kuran projenin kendi lock’u zaten var, kütüphanenin lock’u onunla çakışır ve hiç kullanılmaz. Manifest (package.json, composer.json) commit’lenir, lock dosyası .gitignorea girer. Uygulama projesinde bu istisna geçerli değil, lock dosyası her zaman commit’lenir.
Bu ayrımı unutup bir kütüphanede lock commit’lemek zararsız görünür ama değildir. Kullanan proje kendi lock’unu üretirken kütüphanenin lock’u hiç okunmaz, sadece repoda gereksiz yer kaplar ve her bağımlılık güncellemesinde manuel senkron ister.
PR incelemesinde lock diff’ini satır satır okumayın
pnpm-lock.yaml binlerce satır olabilir, tek bir doğrudan bağımlılık eklemek bile lock’ta yüzlerce satırlık fark açabilir. Bu diff’i satır satır okumak zaman kaybı, gerçek inceleme package.jsonda hangi paketin eklendiğine bakmak. Lock’un görevi o kararı doğrulamak değil, kaydetmek.
Lock çakışması elle çözülmez
İki branch aynı anda bağımlılık eklerse pnpm-lock.yaml merge’de çakışır. Çakışan satırları elle düzeltmek cazip geliyor, ama lock dosyası insan eliyle tutarlı tutulamayacak kadar iç içe geçmiş bir bağımlılık grafiği taşıyor.
Doğru çözüm merge’i tamamlayıp kurulumu yeniden çalıştırmak:
git checkout --theirs pnpm-lock.yaml
pnpm install
git add pnpm-lock.yaml
pnpm install package.jsondaki değişikliklere göre lock’u kendi baştan üretiyor, bu elle çakışma çözmekten daha güvenilir.
Özet
Lock dosyasını commit’leyin, .gitignorea eklemeyin. CI ve Docker’da --frozen-lockfile ve --no-dev kullanarak drift’i build aşamasında yakalayın. Tek istisna yayımlanan kütüphaneler. Lock çakışmasını elle değil, install’u yeniden çalıştırarak çözün.