---
title: 'Paket Kaydı ve Bağımlılıklar'
source: 'https://academia.sh/tr/kurslar/javascript-ekosistemi/paket-kaydi-ve-bagimliliklar'
course: 'Modüller, Araçlar ve Ekosistem'
language: tr
updated: '2026-08-17T18:09:45+00:00'
license: 'CC BY-SA 4.0'
---

# Paket Kaydı ve Bağımlılıklar

Bildirim dosyasının alanları, çıplak belirtecin dizin ağacında aranması, dışa aktarım haritasıyla kapsülleme, bağımlılık türleri ve kilit dosyasının işlevi.

Modül sistemleri konusundaki tüm belirteçler göreli dosya yollarıydı. Gerçek projelerde
içe aktarımların çoğu `bicim-yardimcisi` gibi çıplak adlardır: ne uzantı taşırlar ne de
dizin bilgisi.

Bu ad ile dosya arasındaki bağı kuran şey, dosya sistemindeki bir kural ve paketin kendi
bildirimidir. Ders, önce paketin ne olduğunu tanımlar, sonra çıplak adın nasıl arandığını
adım adım izler.

## Bildirim Dosyası

Bir **paket (package)**, kendi bildirimini taşıyan bir dizindir. **Bildirim dosyası
(manifest)** paketin kimliğini, giriş noktalarını ve bağımlılıklarını tanımlar. Linux'a
Giriş kursundaki paket yöneticisi kavramı dersinde tanıtılan üstverinin dil düzeyindeki
karşılığıdır; alanların işlevi de benzerdir.

Ölçüm kütüphanesinin bildirimi — proje kökündeki `package.json`:

```json
{
  "name": "metin-olcer",
  "version": "0.1.0",
  "type": "module",
  "exports": {
    ".": "./src/index.mjs",
    "./bolumleme": "./src/bolumleme.mjs"
  },
  "files": ["src"],
  "dependencies": {
    "bicim-yardimcisi": "^1.4.0"
  }
}
```

Alanların taşıdığı kararlar:

| Alan | Kararı |
|---|---|
| `name` | Paketin kayıt içindeki benzersiz kimliği |
| `version` | Bu yayının sürümü; kimliğin ikinci parçası |
| `type` | Uzantısı `.js` olan dosyaların hangi modül sistemine göre okunacağı |
| `exports` | Dışarıdan hangi yolların içe aktarılabileceği |
| `files` | Yayımlanan arşive hangi dosyaların gireceği |
| `dependencies` | Çalışması için gereken paketler ve kabul edilen sürüm aralıkları |

Son üç alan tasarım kararıdır, teknik zorunluluk değildir. Hangi dosyanın dışarıdan
görüleceğine, hangisinin yayımlanacağına ve hangi sürümlerin kabul edileceğine paketin
yazarı karar verir.

## Bağımlılık Eklemek

Ölçüm kütüphanesi, ortalama uzunluğu sabit basamakla yazdırmak için küçük bir yardımcıya
bağlanır. Yardımcı paket, kendi bildirimini taşıyan bir dizindir —
`node_modules/bicim-yardimcisi/package.json`:

```json
{
  "name": "bicim-yardimcisi",
  "version": "1.4.0",
  "type": "module",
  "main": "index.mjs"
}
```

```javascript
// dosya: node_modules/bicim-yardimcisi/index.mjs
export function ondalik(sayi, basamak = 2) {
  return sayi.toFixed(basamak);
}
```

Kütüphaneye eklenen rapor modülü bu paketi çıplak adıyla içe aktarır. Aşağıdaki
dosyanın içe aktardığı `src/index.mjs` ve onun kullandığı `src/bolumleme.mjs` ile
`src/istatistik.mjs`, bu konudaki ES Modülleri dersinde yazılmıştı; ölçüm kütüphanesi
aynı ağaç üzerinde büyümeye devam ediyor:

```javascript
// dosya: src/rapor.mjs — src/index.mjs, ölçüm işlevini dışa aktaran giriş noktasıdır
import { ondalik } from 'bicim-yardimcisi';
import { olc } from './index.mjs';

export function rapor(metin) {
  const olcum = olc(metin);
  return `${olcum.sozcukSayisi} sözcük, ortalama ${ondalik(olcum.ortalamaUzunluk)} karakter`;
}
```

```javascript
// dosya: dene.mjs
import { rapor } from './src/rapor.mjs';

console.log(rapor('Modul kendi kapsamini tasir. Betik genel kapsamda calisir.'));
console.log(import.meta.resolve('bicim-yardimcisi').split('/node_modules/')[1]);
```

```
$ node dene.mjs
8 sözcük, ortalama 6.13 karakter
bicim-yardimcisi/index.mjs
```

Burada iki ayrı olgu vardır ve birbirini gerektirmez: paketin **bildirimde yazılı olması**
ve paketin **dizinde bulunması**. Bildirimde yazılı olup dizinde bulunmayan bir paket
çözümleme hatası verir:

```javascript
// dosya: eksik-paket.mjs
import { ondalik } from 'olmayan-paket';

console.log(ondalik(1.5));
```

```
$ node eksik-paket.mjs 2>&1 | grep '^Error' | sed "s|$(pwd -P)/||g"
Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'olmayan-paket' imported from eksik-paket.mjs
```

Ters durum daha sinsidir: dizinde bulunup bildirimde yazılı olmayan bir paket, yerelde
sorunsuz çalışır. Çözümleme yalnızca dosya sistemine bakar, bildirimi denetlemez. Paket
başka bir yere kurulduğunda o dosya orada bulunmayabilir ve hata ilk kullanımda ortaya
çıkar. Bir bağımlılık kullanılıyorsa bildirimde de yazılı olmalıdır; bu kural, sonraki
derslerde ele alınacak ağaç düzenlemelerinin altında yatan varsayımdır.

## Çıplak Belirteç Nasıl Çözülür

Çıplak ad bir dosya yolu değildir; aranması gereken bir addır. Kural tek cümleyle
yazılabilir: içe aktarmayı yapan dosyanın dizininden başlanır, her dizinde `node_modules`
alt dizini içinde bu ada bakılır, bulunamazsa bir üst dizine çıkılır.

Kuralı doğrudan uygulayan bir betik, aramanın gerçekten böyle yürüdüğünü gösterir:

```javascript
// dosya: src/derin/arama.mjs
import { dirname, join } from 'node:path';
import { existsSync } from 'node:fs';
import { fileURLToPath } from 'node:url';

// Çıplak belirtecin arandığı dizinler: bulunulan dizinden köke doğru.
let dizin = dirname(fileURLToPath(import.meta.url));
while (true) {
  const aday = join(dizin, 'node_modules', 'bicim-yardimcisi');
  console.log(`${existsSync(aday) ? 'BULUNDU ' : 'yok     '} ${aday}`);
  if (existsSync(aday) || dizin === '/') break;
  dizin = dirname(dizin);
}

console.log('çalışma zamanının çözdüğü:', import.meta.resolve('bicim-yardimcisi'));
```

```
$ node src/derin/arama.mjs | sed "s|$(pwd -P)|.|"
yok      ./src/derin/node_modules/bicim-yardimcisi
yok      ./src/node_modules/bicim-yardimcisi
BULUNDU  ./node_modules/bicim-yardimcisi
çalışma zamanının çözdüğü: file://./node_modules/bicim-yardimcisi/index.mjs
```

`sed` çağrısı çıktıdaki mutlak yolu kısaltır; son satırdaki adres, o kısaltmanın adres
biçimine uygulanmış hâlidir. Aramanın kendisi dört özelliği açığa çıkarır:

**Konuma bağlıdır.** Aynı ad, farklı dizinlerdeki iki dosya için farklı pakete çözülebilir.
Bu, sonraki derslerde ele alınacak sürüm çakışması çözümünün temelidir.

**Kayıt gerektirmez.** Çözümleme tümüyle yereldir; ağa çıkılmaz. Ağ, paketler dizine
yerleştirilirken kullanılır, çözümleme sırasında değil.

**Paketin kendisi konuşur.** Dizin bulunduktan sonra hangi dosyanın yükleneceğini paketin
bildirimi söyler.

**Belirlenimcidir.** Aynı dosya ağacında aynı belirteç her zaman aynı dosyaya çözülür.
Modül sistemlerinin ilk dersinde sayılan üçüncü güvence budur.

## Dışa Aktarım Haritası

Paket dizini bulunduğunda, dışarıdan hangi yolların erişilebilir olduğunu bildirimdeki
harita belirler. Haritada listelenmeyen bir yol, dizinde bulunsa bile içe aktarılamaz.

Aşağıdaki iki dosya, `metin-olcer` paketini kuran ayrı bir tüketici projededir ve o
projenin dizininde çalıştırılır. Tüketicinin kendi bildirimi — `tuketici/package.json`:

```json
{
  "name": "tuketici",
  "version": "1.0.0",
  "type": "module",
  "dependencies": { "metin-olcer": "^0.1.0" }
}
```

```javascript
// dosya: tuketici/kullan.mjs
import { olc } from 'metin-olcer';
import { sozcuklereBol } from 'metin-olcer/bolumleme';

console.log(olc('Bir cumle. Iki cumle.').sozcukSayisi);
console.log(sozcuklereBol('bir iki uc').length);
```

```
$ node kullan.mjs
4
3
```

```javascript
// dosya: tuketici/derin.mjs — haritada olmayan bir iç dosyaya erişmeye çalışır
import { ortalamaUzunluk } from 'metin-olcer/src/istatistik.mjs';

console.log(ortalamaUzunluk(['bir', 'iki']));
```

```
$ node derin.mjs 2>&1 | grep -E '^Error' | sed "s|$(pwd -P)/||g"
Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './src/istatistik.mjs' is not defined by "exports" in node_modules/metin-olcer/package.json imported from derin.mjs
```

Bu, paket düzeyinde kapsüllemedir. Haritası olmayan bir pakette her iç dosya dışarıya
açıktır; tüketiciler iç dosyalara bağlanır ve dosyaların yeniden düzenlenmesi kırıcı
değişikliğe dönüşür. Harita, kütüphanenin hangi yollarının sözleşme olduğunu ve hangi
dosyalarının serbestçe değiştirilebileceğini ayırır.

## Bağımlılık Türleri

Bildirimde bağımlılıklar tek bir liste değildir; her liste farklı bir soruya yanıt verir.

**Çalışma bağımlılıkları.** Paket çalışırken gereken paketler. Paketi kuran herkes bunları
da kurar.

**Geliştirme bağımlılıkları.** Yalnızca paketi geliştirirken gerekenler: test koşucusu,
çözümleyici, derleme aracı. Paketi kullanan taraf bunları kurmaz. Ayrımın anlamı,
tüketicinin indirdiği ağacın küçük kalmasıdır.

**Eş bağımlılıklar.** Paketin çalışması için gereken, ancak paketin kendisinin kurmaması
gereken bağımlılıklar. Bir eklenti, genişlettiği kütüphanenin **aynı örneğini** kullanmak
zorundaysa bu listeye yazılır; böylece kütüphaneyi kuran taraf uygulamanın kendisi olur ve
ağaçta tek kopya bulunur. Yinelenen kopyanın neden sorun olduğu, bağımlılık ağacı dersinde
gösterilecektir.

**İsteğe bağlı bağımlılıklar.** Kurulumu başarısız olsa da işlemi durdurmayan bağımlılıklar.
Paket, eksikliğe karşı yedek bir yol taşımak zorundadır; taşımıyorsa bu liste yanlış
kullanılmıştır.

## Paket Kaydı ve Kilit Dosyası

**Paket kaydı (package registry)**, ad ve sürüm çiftini bir arşive eşleyen bir dizindir.
Yayımlanmış bir ad–sürüm çiftinin içeriği değiştirilemez kabul edilir: aynı çift her zaman
aynı baytları vermelidir. Bu değişmezlik, sonraki tüm güvencelerin dayanağıdır.

Bildirimdeki `^1.4.0` gibi bir aralık, tek bir sürümü değil bir kümeyi gösterir. Kurulum
zamanı geldiğinde kümeden bir seçim yapılır. İki farklı zamanda yapılan iki kurulum, küme
büyüdüğü için farklı seçimler yapabilir; sonuç, aynı kaynaktan farklı çalışan iki ağaçtır.

**Kilit dosyası (lock file)** bu belirsizliği ortadan kaldırır. Kaydettiği üç bilgi
vardır:

1. **Seçilen kesin sürüm.** Aralık değil, tek bir sürüm numarası.
2. **Kaynak adresi.** Arşivin nereden alındığı.
3. **Bütünlük özeti (integrity digest).** Arşivin içeriğinin sağlaması.

Ayrıca ağacın biçimi — hangi paketin hangi düzeyde durduğu — kaydedilir. Kilit dosyası
bulunduğunda kurulum bir arama değil, bir yeniden üretimdir: yazılı ağaç aynen kurulur.

Bu ayrım, Linux'a Giriş kursundaki bağımlılık çözümlemesinin kısıt problemi olarak
tanımlanmasıyla aynı yerden gelir. Çözümleyicinin ürettiği çözüm, o çözümü yeniden
hesaplamadan saklanabilir olmalıdır; kilit dosyası bunun kaydıdır. Bu nedenle sürüm
denetimine eklenir: bir depoyu klonlayan ikinci geliştiricinin ve yapı sunucusunun aynı
ağacı kurması buna bağlıdır.

## Özet

- Paket, bildirim dosyası taşıyan bir dizindir; bildirim kimliği, giriş noktalarını,
  yayımlanacak dosyaları ve bağımlılıkları tanımlar.
- Çıplak belirteç, içe aktaran dosyanın dizininden köke doğru her düzeydeki `node_modules`
  dizininde aranır; çözümleme yereldir, konuma bağlıdır ve belirlenimcidir.
- Dışa aktarım haritası paket düzeyinde kapsülleme sağlar; haritada olmayan iç dosyalar
  dışarıdan içe aktarılamaz.
- Bağımlılık listeleri farklı sorulara yanıt verir: çalışma, geliştirme, eş ve isteğe bağlı.
- Sürüm aralığı bir küme belirtir; kilit dosyası kümeden yapılan seçimi, kaynağı ve
  bütünlük özetini kaydederek kurulumu yeniden üretilebilir kılar.

## Sonraki Adım

Aralıkların bir küme belirttiği söylendi, ama kümenin sınırlarını neyin çizdiği
söylenmedi. `^1.4.0` yazan bir bildirimin `1.9.0` sürümünü kabul edip `2.0.0` sürümünü
reddetmesinin arkasında, sürüm numarasının parçalarına anlam yükleyen bir sözleşme vardır.
Sonraki ders bu sözleşmeyi ve karşılaştırma kurallarını çalışan kodla kurar.
