JavaScript modül sistemleri arasındaki seçim, projenizin mimarisini ve bakım kolaylığını doğrudan etkiler. CommonJS, Node.js'in geleneksel modül sistemi iken; ES Modules (ESM) modern tarayıcılar ve Node.js tarafından desteklenen resmi standarttır. Peki, hangi durumda hangisini tercih etmelisiniz? Bu yazıda her iki sistemi derinlemesine karşılaştırıyor, pratik örneklerle farklılıkları ortaya koyuyoruz.
CommonJS ve ES Modules Nedir?
CommonJS, Node.js ile popülerleşmiş, senkron bir modül sistemidir. require() ile modülleri yükler, module.exports ile dışa aktarır. Bloklayıcı (blocking) yapısı sayesinde dosya sistemi gibi kaynaklara erişimde sorunsuz çalışır. ES Modules ise ECMAScript 2015 (ES6) ile gelen, asenkron ve statik bir yapıya sahiptir. import ve export anahtar kelimelerini kullanır. Tarayıcılar tarafından yerel olarak desteklenir ve statik analize olanak tanır.
Karşılaştırma Tablosu: CommonJS vs ES Modules
| Özellik | CommonJS (CJS) | ES Modules (ESM) |
|---|---|---|
| Söz Dizimi | require() / module.exports |
import / export |
| Yükleme Zamanı | Senkron (çalışma zamanı) | Asenkron (derleme zamanı ve çalışma zamanı) |
| Statik Analiz | Desteklemez (dinamik) | Destekler (statik; ağaç sallama, ölü kod temizliği) |
| Tarayıcı Desteği | Yerel destek yok (bundler gerekir) | Doğrudan desteklenir (script type="module") |
| Node.js Desteği | Tam destek (varsayılan) | Desteklenir (package.json'da "type": "module") |
| Döngüsel Bağımlılıklar | Kısmen çalışır (kopya gönderir) | Daha iyi yönetir (henüz tanımlanmamış bağlama) |
| Performans | Basit, düşük ek yük | Statik analiz sayesinde tree-shaking ile daha iyi |
Ne Zaman Hangi Sistemi Seçmelisiniz?
Node.js Backend Projeleri
Eğer yeni bir proje başlatıyorsanız ve Node.js sürümünüz 12 veya üzeriyse, ES Modules kullanmanız önerilir. Modern özellikler (statik import, top-level await) ve daha iyi araç desteği sunar. Ancak halen büyük bir eko sisteme sahip olan CommonJS, mevcut projelerde veya tam uyumluluk gerektiğinde güvenli bir tercihtir. Örneğin, Node.js'de N+1 Problemi gibi konuları incelerken, modül sisteminizin kod organizasyonunuzu nasıl etkilediğini göz önünde bulundurun.
Tarayıcı Tabanlı Projeler
ES Modules burada açık ara kazanan konumda. Tarayıcılar doğrudan ESM'yi destekler, bu nedenle bir bundleyici (Webpack, Vite, vb.) kullanmadan da çalıştırabilirsiniz. CommonJS'i tarayıcıda kullanmak için ek araçlara ihtiyaç duyarsınız. Bu nedenle yeni bir frontend projesinde ES Modules standarttır.
Karma Projeler (Hem Backend Hem Frontend)
Monorepo yapıları genellikle her iki sistemi de barındırır. Bu durumda ES Modules'ü tercih ederek birlikte çalışabilirliği artırabilirsiniz. Ancak bazı NPM paketleri halen yalnızca CommonJS olarak dağıtıldığı için, createRequire gibi köprüler kullanmanız gerekebilir.
Sık Yapılan Hatalar
- package.json'da type alanını yanlış ayarlamak:
"type": "module"eklemeden ESM kullanmaya çalışmak hatalara yol açar. CommonJS dosyalarınızın uzantısını.cjsyaparak eski sistemle uyum sağlayabilirsiniz. - Node.js'de require() ile ESM dosyası yüklemek: ES Modules dosyaları (çoğunlukla
.mjsveya"type": "module"altındaki.js)require()ile yüklenemez;import()dinamik ifadesini kullanmalısınız. - Tarayıcıda CommonJS kullanmak: Webpack gibi bir bundler olmadan CommonJS tarayıcıda çalışmaz. ESM kullanın veya uygun bir derleyici entegre edin.
Pratik Örnekler
CommonJS Örneği
// math.js
const add = (a, b) => a + b;
module.exports = { add };
// main.js
const { add } = require('./math');
console.log(add(2, 3)); // 5
ES Modules Örneği
// math.js
export const add = (a, b) => a + b;
// main.js
import { add } from './math.js';
console.log(add(2, 3)); // 5
Gördüğünüz gibi söz dizimi farklıdır. ESM'de dosya uzantısı zorunludur (tarayıcı için) ve statik import en üstte olmalıdır.
Geçiş Stratejileri
Mevcut bir CommonJS projesini ESM'ye taşırken adım adım ilerleyin:
- package.json'a
"type": "module"ekleyin. - Uzantıları
.mjsveya.jsolarak düzenleyin (CommonJS kalan dosyalar için.cjskullanın). require()çağrılarınıimportile değiştirin.- Döngüsel bağımlılıkları kontrol edin; ESM'de daha katıdır.
- Testleri çalıştırın. JavaScript Promise ve Async/Await ile Hata Yönetimi yazımızda asenkron modüllerin hata yönetimine dair pratik ipuçları bulabilirsiniz.
Sonuç
CommonJS, Node.js ekosisteminde derin köklere sahip olsa da, ES Modules modern JavaScript'in geleceğidir. Yeni projelerde ESM kullanmak; tree-shaking, statik analiz ve daha iyi tarayıcı uyumu gibi avantajlar sunar. Mevcut projelerde ise geçiş maliyetini değerlendirerek yavaşça ESM'ye yönelin. Modül sistemleri arasındaki farkları anlamak, daha temiz ve sürdürülebilir kod yazmanıza yardımcı olacaktır.
Sık Sorulan Sorular
CommonJS ile ES Modules arasında performans farkı var mı?
Evet, özellikle büyük projelerde ES Modules'un statik yapısı sayesinde tree-shaking ve ölü kod temizliği daha etkilidir. CommonJS daha basit olsa da, derleme zamanı optimizasyonlarından yoksundur.
Node.js'de varsayılan modül sistemi hangisidir?
Node.js'in varsayılan modül sistemi CommonJS'tir. Ancak package.json'da "type": "module" ekleyerek ES Modules'u varsayılan yapabilirsiniz.
Tarayıcıda CommonJS kullanabilir miyim?
Hayır, tarayıcılar CommonJS'i doğrudan desteklemez. Ancak Webpack, Rollup veya Vite gibi bir bundleyici ile CommonJS kodunu ESM'ye dönüştürebilirsiniz.
Bir projede hem CommonJS hem ES Modules kullanabilir miyim?
Evet, ancak dikkatli olmalısınız. Node.js'de CommonJS dosyaları .cjs, ESM dosyaları .mjs veya .js (type:module altında) olarak ayrılabilir. Çapraz yüklemelerde dinamik import() veya createRequire kullanın.
ES Modules kullanmanın dezavantajları var mı?
ES Modules, senkron olmayan yapısı nedeniyle bazı eski paketlerle uyumsuzluk yaşayabilir. Ayrıca CommonJS kadar yaygın olmayan modüllerin import edilmesi ek yapılandırma gerektirebilir.






