---
title: 'ES Modülleri'
source: 'https://academia.sh/tr/kurslar/javascript-ekosistemi/es-modulleri'
course: 'Modüller, Araçlar ve Ekosistem'
language: tr
updated: '2026-08-17T18:09:45+00:00'
license: 'CC BY-SA 4.0'
---

# ES Modülleri

Adlandırılmış ve varsayılan dışa aktarım, içe aktarımın canlı bağ davranışı, bağlamanın değerlendirmeden önce gelmesi ve statik yapının ağaç sarsmaya verdiği imkân.

Önceki ders tek dosyalık ölçüm betiğini bırakırken asıl soruyu ortaya koymuştu: dosya
bölünürken hangi adın dışarıdan görülebilir kalacağına kim karar verir? Dilin standart
modül sözdiziminde bu kararı modülün kendisi verir ve kararını kaynağın içinde yazılı
olarak bildirir.

Bu ders o sözdizimini ve arkasındaki mekanizmayı ele alır. Sözdizim kısa; mekanizma,
kurs boyunca kullanılacak birkaç davranışın kaynağıdır.

## Dışa Aktarım Yüzeyi

Ölçüm betiği üç sorumluluğa bölünür. Metni parçalara ayırma işi bir modüle, sayısal ölçüm
ikinci bir modüle, ikisini birleştiren giriş noktası üçüncüsüne gider.

```javascript
// dosya: src/bolumleme.mjs
const SOZCUK_AYIRACI = /[^\p{L}\p{N}]+/u;
const CUMLE_AYIRACI = /[.?]+/;

export function sozcuklereBol(metin) {
  return metin.split(SOZCUK_AYIRACI).filter((s) => s.length > 0);
}

export function cumlelereBol(metin) {
  return metin.split(CUMLE_AYIRACI).map((c) => c.trim()).filter((c) => c.length > 0);
}
```

```javascript
// dosya: src/istatistik.mjs
export function ortalamaUzunluk(sozcukler) {
  if (sozcukler.length === 0) return 0;
  const toplam = sozcukler.reduce((t, s) => t + s.length, 0);
  return toplam / sozcukler.length;
}

export function enUzunSozcuk(sozcukler) {
  return sozcukler.reduce((en, s) => (s.length > en.length ? s : en), '');
}
```

```javascript
// dosya: src/index.mjs
import { cumlelereBol, sozcuklereBol } from './bolumleme.mjs';
import { enUzunSozcuk, ortalamaUzunluk } from './istatistik.mjs';

export function olc(metin) {
  const sozcukler = sozcuklereBol(metin);
  return {
    sozcukSayisi: sozcukler.length,
    cumleSayisi: cumlelereBol(metin).length,
    ortalamaUzunluk: ortalamaUzunluk(sozcukler),
    enUzun: enUzunSozcuk(sozcukler),
  };
}

export { cumlelereBol, sozcuklereBol };
```

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

console.log(olc('Modul kendi kapsamini tasir. Betik genel kapsamda calisir.'));
```

```
$ node dene.mjs
{
  sozcukSayisi: 8,
  cumleSayisi: 2,
  ortalamaUzunluk: 6.125,
  enUzun: 'kapsamini'
}
```

İki ayrıntı önemlidir. Birincisi, `SOZCUK_AYIRACI` sabiti artık yalnızca kendi modülünde
görünür; `export` almadığı için dışarıdan erişilemez. Görünürlük, dosya sınırının değil,
bildirimin özelliğidir.

İkincisi, `index.mjs` dosyasının son satırı iki adı **yeniden dışa aktarır**. Giriş
noktası, alt modüllerin bir bölümünü kendi yüzeyine taşıyarak paketin dışarıya sunduğu
arayüzü tek yerde toplar. `ortalamaUzunluk` ve `enUzunSozcuk` bu listeye alınmadı: iç
hesaplama ayrıntısı olarak kaldılar. Dışa aktarım yüzeyi bir tasarım kararıdır ve
kütüphanenin ileride ne kadar değişebileceğini belirler.

## Adlandırılmış ve Varsayılan Dışa Aktarım

İki biçim vardır. **Adlandırılmış dışa aktarım (named export)** bir adı yüzeye koyar;
tüketici o adı yazarak alır. **Varsayılan dışa aktarım (default export)** adsız tek bir
değer sunar; tüketici ona istediği adı verir.

```javascript
export function olc(metin) { /* ... */ }        // adlandırılmış
export default function olc(metin) { /* ... */ }  // varsayılan
```

Ayrım yalnızca yazım kolaylığı değildir. Adlandırılmış dışa aktarımda ad, modülün
sözleşmesinin parçasıdır: yanlış yazılan bir ad bağlama aşamasında yakalanır. Varsayılan
dışa aktarımda ad tüketicinin seçimidir; iki dosyanın aynı değeri farklı adlarla
çağırması mümkündür ve otomatik araçlar bu adı izleyemez. Kütüphane arayüzlerinde
adlandırılmış biçim, adın kararlı kalması gereken durumlar için daha güçlü bir sözleşme
kurar.

## İçe Aktarılan Ad Bir Bağdır

İçe aktarma, değeri kopyalamaz; dışa aktaran modüldeki bildirime bir **canlı bağ (live
binding)** kurar. Dışa aktaran modül değeri değiştirdiğinde, içe aktaran taraf yeni değeri
görür.

```javascript
// dosya: kayit.mjs
console.log('kayit.mjs gövdesi çalıştı');
export let cagriSayisi = 0;
export function say() { cagriSayisi += 1; }
```

```javascript
// dosya: ana.mjs
console.log('ana.mjs gövdesinin ilk satırı');
import { cagriSayisi, say } from './kayit.mjs';

console.log('içe aktarılan değer:', cagriSayisi);
say();
say();
console.log('iki çağrıdan sonra:', cagriSayisi);
```

```
$ node ana.mjs
kayit.mjs gövdesi çalıştı
ana.mjs gövdesinin ilk satırı
içe aktarılan değer: 0
iki çağrıdan sonra: 2
```

`cagriSayisi` sayısal bir değerdir, yani değiştirilemez bir ilkel; buna rağmen ikinci okuma
2 verdi. Okunan şey değer değil, bağdır.

Bağ tek yönlüdür. İçe aktaran taraf bağa yazamaz:

```javascript
// dosya: atama.mjs — kayit.mjs yukarıdaki dosyadır
import { cagriSayisi } from './kayit.mjs';

cagriSayisi = 5;
```

```
$ node atama.mjs 2>&1 | grep -E 'Error' | head -1
TypeError: Assignment to constant variable.
```

Bu kısıt, bir modülün durumunu yalnızca kendi kodunun değiştirebileceğini garanti eder.
Dışarıdan değişiklik isteniyorsa modül bunun için bir fonksiyon dışa aktarmalıdır.

## Bağlama Değerlendirmeden Önce Gelir

Çıktıdaki satır sırası dikkat çekicidir: `kayit.mjs` gövdesi, `ana.mjs` dosyasının kendi
konsol yazımından **önce** çalıştı. Oysa içe aktarma deyimi o yazımdan sonra geliyordu.

Bunun nedeni, modül yüklemenin üç ayrı aşamada yürümesidir:

1. **Ayrıştırma ve çözümleme.** Kaynak okunur, içe aktarma belirteçleri (specifier)
   dosyalara çevrilir; bulunan her dosya için işlem yinelenir. Sonuç bir modül çizgesidir.
2. **Bağlama.** Her içe aktarılan ad, dışa aktaran modüldeki bildirimle eşleştirilir.
   Karşılığı bulunamayan ad burada hata verir.
3. **Değerlendirme.** Modül gövdeleri, bağımlılıktan bağımlıya doğru bir kez çalıştırılır.

Bilgisayarlar Nasıl Çalışır kursundaki bağlama ve yükleme dersinde bağlayıcının yaptığı iş
buydu: simgeleri çözmek ve eksik olanı bildirmek. Modül sisteminin ikinci aşaması aynı işi
kaynak düzeyinde yapar. Sonucu da benzerdir — eksik ad, kod çalışmadan yakalanır:

```javascript
// dosya: hatali.mjs — kayit.mjs yalnızca cagriSayisi ve say adlarını dışa aktarır
import { cagriSayisi, sayac } from './kayit.mjs';

console.log('bu satır hiç çalışmaz', cagriSayisi, sayac);
```

```
$ node hatali.mjs 2>&1 | grep 'SyntaxError'
SyntaxError: The requested module './kayit.mjs' does not provide an export named 'sayac'
```

Hata türü dikkat çekicidir: sözdizim hatası. Modül grafiğinin tutarlılığı, program
başlamadan denetlenen bir özelliktir. Aynı şey eksik dosya için de geçerlidir:

```javascript
// dosya: eksik-bagimlilik.mjs
console.log('bu satır çalışmaz');
import './olmayan-modul.mjs';
```

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

Konsola hiçbir şey yazılmadı. `sed` çağrısı yalnızca iletideki mutlak dizin yolunu
kısaltmak içindir; yol, çalıştırdığınız dizine göre değişir.

## Ad Alanı Nesnesi

Bir modülün tüm dışa aktarımları tek bir nesnede toplanarak da alınabilir:

```javascript
// dosya: adalani.mjs — src/index.mjs yukarıda tanımlanan giriş noktasıdır
import * as olcer from './src/index.mjs';

console.log(Object.keys(olcer));
console.log(Object.isFrozen(olcer));
console.log(olcer[Symbol.toStringTag]);
```

```
$ node adalani.mjs
[ 'cumlelereBol', 'olc', 'sozcuklereBol' ]
false
Module
```

Anahtarların sırası, kaynaktaki yazım sırası değil, sözlük sırasıdır: ad alanı nesnesinin
içeriği kaynak metnin düzeninden bağımsız, belirlenimci bir şekilde üretilir. Nesne
dondurulmuş değildir ama genişletilemez; üzerine yeni ad eklenemez, var olan adlar
silinemez.

## Statik Yapının Sonucu

İçe ve dışa aktarma deyimleri yalnızca en üst düzeyde bulunabilir ve belirteçleri sabit
dizgi olmak zorundadır. Bu kısıt, ilk bakışta esnekliği azaltan bir katılık gibi görünür;
karşılığında kod çalıştırılmadan çözümlenebilir hâle gelir.

Somut kazanç, kullanılmayan dışa aktarımların çıktıdan düşürülebilmesidir; buna **ağaç
sarsma (tree shaking)** denir. Bir araç, `index.mjs` dosyasının yalnızca `olc` adını
kullandığını kaynağa bakarak görebilir ve `cumlelereBol` işlevini çıktıya hiç koymayabilir.
Aynı çıkarımı, adların çalışma anında hesaplandığı bir sistemde yapmak genel olarak
olanaksızdır.

İkinci kazanç, araçların modül çizgesini programı çalıştırmadan kurabilmesidir. Kurs
boyunca göreceğiniz paketleyici, çözümleyici ve düzenleyici desteklerinin tümü bu
özelliğe dayanır.

## Özet

- Dışa aktarım bildirim düzeyinde belirlenir; `export` almayan ad, dosya dışından
  erişilemez ve giriş noktası yeniden dışa aktarımla arayüzü tek yerde toplar.
- Adlandırılmış dışa aktarımda ad sözleşmenin parçasıdır ve yanlış yazımı bağlama
  aşamasında yakalanır; varsayılan dışa aktarımda adı tüketici seçer.
- İçe aktarılan ad değerin kopyası değil, dışa aktaran modüldeki bildirime kurulmuş canlı
  bağdır ve içe aktaran taraftan yazılamaz.
- Yükleme üç aşamalıdır: çözümleme, bağlama, değerlendirme. Eksik ad ve eksik dosya
  hataları ilk iki aşamada, hiçbir gövde çalışmadan çıkar.
- Sözdizimin statik olması ağaç sarsmayı ve çizgenin kod çalıştırılmadan kurulmasını
  mümkün kılar.

## Sonraki Adım

Bu modeli tek seçenek sanmak yanıltıcı olur. Dilin daha eski ve hâlâ yaygın olarak
karşılaşılan ikinci bir modül sistemi vardır; orada içe aktarma bir deyim değil, bir
fonksiyon çağrısıdır ve tüm davranışlar buradan farklılaşır. Sonraki ders o sistemi,
bu sistemle birlikte nasıl yaşadığını ve dairesel bağımlılıkta ikisinin nasıl ayrıştığını
inceler.
