---
title: 'Modül İhtiyacı'
source: 'https://academia.sh/tr/kurslar/javascript-ekosistemi/modul-ihtiyaci'
course: 'Modüller, Araçlar ve Ekosistem'
language: tr
updated: '2026-08-17T18:09:45+00:00'
license: 'CC BY-SA 4.0'
---

# Modül İhtiyacı

Genel kapsamın paylaşılmasından doğan ad çakışması sorunu, kapanışla kurulan ad alanı kalıbı ve modül kapsamının bu soruna verdiği yanıt.

Eşzamansız JavaScript ve Çalışma Zamanı kursu, tek bir programın nasıl yürüdüğünü ve
sorunlarının nasıl tanılandığını ele aldı. Bu kurs bir üst düzeye çıkar: bir program tek
dosyada durmadığında, parçaların birbirini nasıl bulduğu ve kimin neyi görebildiği sorusuna.

Soru masum görünür. Kodu iki dosyaya bölmek, dosyaları birbiri ardına yüklemekten ibaret
sanılır. Bu varsayımın nerede kırıldığını görmek, modül kavramının neden dile eklendiğini
de açıklar.

## Genel Kapsam Ortak Bir Kaynaktır

Dilin ilk yürütme birimi **betik (script)** idi: kaynak metin ayrıştırılır ve en üst
düzeydeki bildirimleri genel kapsama yazılır. İki ayrı dosya, aynı çalışma zamanında art
arda yüklendiğinde ayrı bir dünya kurmaz; ikisi de aynı genel nesneye yazar.

Bu davranış, çalışma zamanının betik değerlendirme arayüzüyle doğrudan gözlenebilir:

```javascript
// dosya: betikler.mjs
import vm from 'node:vm';

// İki ayrı "betik", aynı genel kapsamda çalıştırılıyor.
vm.runInThisContext('var surum = "cizim-1.0"; function bicimle(d) { return "cizim: " + d; }');
vm.runInThisContext('var surum = "rapor-2.0"; function bicimle(d) { return "rapor: " + d; }');

console.log(globalThis.surum);
console.log(globalThis.bicimle('x'));
```

```
$ node betikler.mjs
rapor-2.0
rapor: x
```

İlk betiğin `surum` değişkeni ve `bicimle` fonksiyonu kayboldu. Hata yok, uyarı yok:
ikinci bildirim birincinin üzerine yazdı. Program çalışmaya devam eder ve yanlış sonuç
üretir.

Sorunun büyüklüğü dosya sayısıyla değil, **ad sayısıyla** artar. Yirmi dosyanın her biri
beş genel ad tanımlıyorsa yüz adlık ortak bir havuz oluşur ve bu havuzun çakışmasız
kalması yalnızca yazarların dikkatine bağlıdır. Programlama Temelleri kursunda kurulan
kapsam kavramı burada işletim düzeyinde bir soruna dönüşür: paylaşılan yazılabilir bir ad
alanı, yalıtımsız bir kaynaktır.

İkinci sorun sıralamadır. Bir dosya diğerinin tanımladığı fonksiyonu kullanıyorsa yükleme
sırası önemlidir, ama bu sıra kodun kendisinde yazılı değildir; onu yükleyen tarafın
bilmesi gerekir. Bağımlılık bilgisi kaynakta değil, kaynağın dışında durur.

## Kapanışla Kurulan Ad Alanı

Dilde modül sözdizimi yokken bu iki soruna verilen yanıt, kapanışların (closure) kapsam
yalıtımı özelliğini kullanmaktı. Bir fonksiyon tanımlanıp hemen çağrılır, iç adlar o
fonksiyonun kapsamında kalır, dışarıya yalnızca seçilmiş bir nesne verilir:

```javascript
// dosya: iife.mjs
var Olcer = (function () {
  var ayirac = /\s+/;
  function sozcukler(metin) { return metin.trim().split(ayirac); }
  return { sozcukler: sozcukler };
})();

console.log(Olcer.sozcukler('bir iki  uc'));
console.log(typeof ayirac);
```

```
$ node iife.mjs
[ 'bir', 'iki', 'uc' ]
undefined
```

`ayirac` dışarıdan görünmez; yalnızca `Olcer` adı genel kapsama yazılır. Bu kalıp, JavaScript'te
Nesneler ve Fonksiyonlar kursundaki hemen çağrılan fonksiyon kalıbının doğrudan
uygulamasıdır ve gerçek bir kazanç sağlar: yüz genel ad yerine bir genel ad.

Kazandırdığı kadarını da kaybettirir. Ad alanı nesnesinin kendisi hâlâ genel kapsamdadır
ve çakışabilir. Bağımlılıklar yine sözleşmeyle taşınır: `Olcer`, kendisinden önce bir
başka ad alanının yüklenmiş olmasını bekliyorsa bunu yazılı olarak bildiremez. Dahası
hangi adın nereden geldiği, kaynağa bakılarak değil, tüm dosyalar taranarak bulunur.

## Modül Kapsamı

Modül, bu sorunları dilin ayrıştırma düzeyinde çözer. Bir kaynak metin **modül (module)**
olarak ayrıştırıldığında en üst düzeydeki bildirimleri genel kapsama değil, o modüle özgü
bir kapsama yazılır:

```javascript
// dosya: kapsam.mjs
const surum = 'metin-olcer-1.0';
function bicimle(d) { return 'olcer: ' + d; }

console.log(typeof globalThis.surum);   // modül kapsamındaki ad genel nesnede yok
console.log(typeof globalThis.bicimle);
console.log(this);                      // modülün en üst düzeyinde this
```

```
$ node kapsam.mjs
undefined
undefined
undefined
```

Üç çıktı da aynı şeyi söyler: modülün en üst düzeyi, genel kapsam değildir. `surum` ve
`bicimle` adları dışarıdan görünmez; en üst düzeydeki `this` genel nesneye değil,
tanımsıza bağlanır.

Ad alanı kalıbıyla arasındaki fark, yalıtımın kaynağıdır. Kapanış kalıbında yalıtım
programcının kurduğu bir yapıydı ve bozulabilirdi; modülde yalıtım ayrıştırıcının
kararıdır ve bozulamaz.

## Betik ile Modülün Ayrımı

Aynı kaynak metin, iki farklı kural kümesiyle ayrıştırılabilir. Ayrım yalnızca kapsamla
sınırlı değildir:

| Ölçüt | Betik | Modül |
|---|---|---|
| En üst düzey bildirimler | Genel kapsama yazılır | Modül kapsamında kalır |
| En üst düzeydeki `this` | Genel nesne | Tanımsız |
| Katı kip | Açıkça istenmelidir | Her zaman etkindir |
| İçe/dışa aktarım sözdizimi | Geçersiz | Geçerli |
| Değerlendirme zamanı | Karşılaşıldığı anda | Bağımlılıklar çözüldükten sonra |

Son satır belirleyicidir ve sonraki derste ayrıntılandırılacaktır. Bir metnin hangi kurala
göre ayrıştırılacağı, çalışma zamanının okuduğu bir işaretle belirlenir: dosya uzantısı,
bildirim dosyasındaki tip alanı ya da betiği yükleyen tarafın verdiği tür bilgisi. Aynı
karakter dizisi, bu işarete göre farklı anlam kazanır.

## Bir Modül Sisteminden Beklenenler

Bir modül sisteminin çözmesi gereken sorunlar, yukarıdaki iki denemeden çıkarılabilir:

**Yalıtım.** Modülün iç adları dışarıdan görünmemeli; dışarıya ne verdiğini modülün kendisi
seçmeli.

**Açık arayüz.** Bir modülün neye bağlı olduğu ve ne sunduğu, kaynağın kendisinde yazılı
olmalı. Bağımlılık bilgisi yükleyicinin belleğinde değil, kodda durmalı.

**Belirlenimci çözümleme.** Bir bağımlılık adı, her ortamda aynı dosyaya karşılık gelmeli.
Ad çözümleme kuralı yazılı ve öngörülebilir olmalı.

**Tek değerlendirme.** Aynı modül birden çok yerden istendiğinde bir kez değerlendirilmeli;
tuttuğu durum tüm kullanıcılar için aynı olmalı. Bu güvence, Bilgisayarlar Nasıl Çalışır
kursundaki bağlama ve yükleme dersinde tanıtılan simge çözümlemesinin dil düzeyindeki
karşılığıdır: bir ad, tek bir tanıma bağlanır.

Bu dört güvence, kurs boyunca incelenecek her mekanizmanın ölçütüdür. Paket çözümlemesi
üçüncüsünün, önbellekleme dördüncüsünün gerçekleştirimidir.

## Kursun Örneği

Kurs boyunca tek bir somut örnek geliştirilecektir: `metin-olcer` adlı küçük bir kütüphane
paketi. İşi, verilen metnin sözcük ve cümle sayısını, ortalama sözcük uzunluğunu ve en uzun
sözcüğünü hesaplamaktır. Tek dosyalık bir betik olarak başlar; modüllere bölünür, dışa
aktarım yüzeyi tanımlanır, bir bağımlılık ekler, sürüm işaretlenir, bir çalışma alanının
parçası olur ve sonunda derleme ile çözümleme araçlarına bağlanır.

İlk hâli tek dosyadır ve hiçbir şey dışa aktarmaz:

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

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

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

function ortalamaUzunluk(sozcukler) {
  if (sozcukler.length === 0) return 0;
  return sozcukler.reduce((t, s) => t + s.length, 0) / sozcukler.length;
}

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

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

```
$ node olcer.mjs
{ sozcukSayisi: 8, cumleSayisi: 2, ortalamaUzunluk: 6.125 }
```

Bu dosyada üç ayrı sorumluluk iç içedir: metni parçalara ayırma, sayısal ölçüm hesaplama ve
sonucu sunma. Üçü de aynı kapsamı paylaştığı için birbirinin adlarını doğrudan görür. Dosya
büyüdükçe bu görünürlük bir tasarım kararı olmaktan çıkıp bir kaza kaynağına dönüşür:
`SOZCUK_AYIRACI` sabiti yalnızca bölme işlevlerini ilgilendirdiği hâlde tüm dosyaya açıktır.

Bir sonraki derste bu dosya sorumluluklarına göre bölünecek ve bölünmenin dışa aktarım
yüzeyine etkisi incelenecektir. Bölme işleminin asıl sorusu, hangi kodun hangi dosyaya
gideceği değil, **hangi adın dışarıdan görülebilir kalacağıdır**.

## Özet

- Betik olarak ayrıştırılan kaynağın en üst düzey bildirimleri genel kapsama yazılır; iki
  dosya aynı adı tanımladığında ikincisi birincisini sessizce geçersizleştirir.
- Kapanışla kurulan ad alanı kalıbı genel ad sayısını azaltır, ancak yalıtımı programcının
  disiplinine bırakır ve bağımlılıkları kodda bildirmez.
- Modül olarak ayrıştırılan kaynağın en üst düzey bildirimleri modül kapsamında kalır; katı
  kip her zaman etkindir ve en üst düzeydeki `this` tanımsızdır.
- Bir modül sistemi dört güvence verir: yalıtım, açık arayüz, belirlenimci çözümleme ve tek
  değerlendirme.

## Sonraki Adım

Modül kapsamı, adların dışarı sızmasını engeller; ama bir modülün başka bir modüle bilerek
ne verdiğini henüz tanımlamadık. Sonraki ders, dilin standart modül sözdizimini ele alır:
dışa aktarım biçimleri, içe aktarımın bağ kurma davranışı ve bu sözdiziminin statik
yapısının neden yalnızca bir yazım tercihi olmadığı.
