farkmt2official 1
farkmt2official
mannaxxx 1
mannaxxx
Bvural41 1
Bvural41
Agora Metin2 1
Agora Metin2
berkmenoo 1
berkmenoo
Hikaye Ekle

[NODE JS] Module Sistemi: require ve module.exports

nodejs.png


[NODE JS] Module Sistemi: require ve module.exports​


Selam arkadaşlar. Bugün Node.js'in temelini oluşturan modül sisteminden bahsedeceğiz: CommonJS. Node.js doğduğundan beri require ve module.exports ile çalışıyor. Bu sistemi anlamadan Node.js ile ciddi bir proje geliştirmek mümkün değil. Ben ilk başlarda her şeyi tek dosyaya yazıyordum, sonra modüler yapıyı öğrenince kod organizasyonum tamamen değişti.

require Nasıl Çalışır?​


require fonksiyonu bir modülü yükler ve o modülün dışa aktardığı değeri döndürür. Üç tür modül yüklenebilir: dahili modüller (fs, path, http gibi), npm paketleri (express, lodash gibi) ve kendi yazdığınız dosyalar. Node.js, require çağrıldığında modülü bir kez yükler ve cache'ler, sonraki require çağrılarında aynı cache'ten döner. Bu önemli bir detay çünkü modül her require edildiğinde yeniden çalışmaz.

Tecrübeme göre modül yükleme sırasını ve çözümleme mantığını anlamak çok önemli. Node.js önce dahili modüllere bakar, sonra node_modules klasörüne, sonra dosya yollarına. Bu sıralamayı bilmezseniz neden bazı modüller bulunamıyor diye saatlerce uğraşabilirsiniz.

JavaScript:
// === REQUIRE KULLANIMI ===

// 1. Dahili (built-in) modüller - isim ile yüklenir
const fs = require('fs');
const path = require('path');
const http = require('http');
const os = require('os');
const crypto = require('crypto');

// 2. npm paketleri - isim ile yüklenir (node_modules'dan)
// const express = require('express');
// const lodash = require('lodash');

// 3. Kendi dosyalarınız - yol ile yüklenir
// const config = require('./config');        // ./config.js
// const utils = require('./utils/helpers');   // ./utils/helpers.js
// const data = require('./data.json');        // JSON dosyası da require edilebilir

// Require çözümleme sırası
// require('modül') çağrıldığında:
// 1. Dahili modül mü? (fs, path, http...) -> Dahili modülü yükle
// 2. ./ veya ../ ile başlıyor mu? -> Dosya yolunu çözümle
//    a. Tam dosya adı (./dosya.js)
//    b. .js uzantısı ekle (./dosya -> ./dosya.js)
//    c. .json uzantısı ekle (./dosya -> ./dosya.json)
//    d. .node uzantısı ekle (./dosya -> ./dosya.node)
//    e. Klasör ise -> klasör/index.js ara
// 3. node_modules'da ara (yukarı doğru tüm dizinlerde)

// Modül caching örneği
console.log('--- Modül Cache ---');
const fs1 = require('fs');
const fs2 = require('fs');
console.log('Aynı referans mı:', fs1 === fs2); // true (cache'ten gelir)

// Cache'i görmek için
console.log('Cache boyutu:', Object.keys(require.cache).length);

// JSON dosyası require etme
// const paketBilgi = require('./package.json');
// console.log(paketBilgi.name, paketBilgi.version);

// Koşullu require (dinamik yükleme)
function veritabaniBaglantisi(tip) {
    let driver;
    switch (tip) {
        case 'mysql':
            // driver = require('mysql2');
            console.log('MySQL driver yüklenecek');
            break;
        case 'postgres':
            // driver = require('pg');
            console.log('PostgreSQL driver yüklenecek');
            break;
        case 'mongodb':
            // driver = require('mongodb');
            console.log('MongoDB driver yüklenecek');
            break;
        default:
            throw new Error(`Desteklenmeyen veritabanı: ${tip}`);
    }
    return driver;
}
veritabaniBaglantisi('postgres');

module.exports ve exports​


Her Node.js dosyası aslında bir modüldür ve dışarıya bir değer aktarır. module.exports ile tek bir değer (fonksiyon, class, obje) aktarabilirsiniz. exports ise module.exports'un bir kısayoludur ama dikkatli kullanılması gerekir. Ben genelde module.exports kullanıyorum çünkü daha açık ve kafa karıştırmıyor.

Yeni başlayanlar exports ile module.exports farkını karıştırıyor. exports, module.exports'a referans verir. Ama exports'a yeni bir değer atarsanız bu referans kopar ve modül hala eski module.exports'u dışa aktarır. Bu yüzden module.exports kullanmak daha güvenli.

JavaScript:
// === MODULE.EXPORTS KULLANIMI ===

// ---- matematik.js ----
// Yöntem 1: Tek tek ekleme
// exports.topla = (a, b) => a + b;
// exports.cikar = (a, b) => a - b;
// exports.carp = (a, b) => a * b;
// exports.bol = (a, b) => b !== 0 ? a / b : null;

// Yöntem 2: Obje olarak dışa aktarma (benim tercihim)
// module.exports = {
//     topla: (a, b) => a + b,
//     cikar: (a, b) => a - b,
//     carp: (a, b) => a * b,
//     bol: (a, b) => b !== 0 ? a / b : null,
//     PI: 3.14159
// };

// Yöntem 3: Tek fonksiyon dışa aktarma
// module.exports = function hesapla(islem, a, b) { ... };

// Yöntem 4: Class dışa aktarma
// module.exports = class Veritabani { ... };

// ---- Pratik örnek: logger modülü ----
// logger.js dosyası olarak düşünün
const loggerModulu = (function() {
    const renkler = {
        reset: '\x1b[0m',
        kirmizi: '\x1b[31m',
        yesil: '\x1b[32m',
        sari: '\x1b[33m',
        mavi: '\x1b[34m',
        gri: '\x1b[90m'
    };

    function formatTarih() {
        return new Date().toISOString().replace('T', ' ').substr(0, 19);
    }

    function info(mesaj, ...args) {
        console.log(`${renkler.mavi}[INFO]${renkler.reset} ${renkler.gri}${formatTarih()}${renkler.reset} ${mesaj}`, ...args);
    }

    function warn(mesaj, ...args) {
        console.warn(`${renkler.sari}[WARN]${renkler.reset} ${renkler.gri}${formatTarih()}${renkler.reset} ${mesaj}`, ...args);
    }

    function error(mesaj, ...args) {
        console.error(`${renkler.kirmizi}[ERROR]${renkler.reset} ${renkler.gri}${formatTarih()}${renkler.reset} ${mesaj}`, ...args);
    }

    function success(mesaj, ...args) {
        console.log(`${renkler.yesil}[OK]${renkler.reset} ${renkler.gri}${formatTarih()}${renkler.reset} ${mesaj}`, ...args);
    }

    // module.exports = { info, warn, error, success };
    return { info, warn, error, success };
})();

// Kullanım
// const logger = require('./logger');
const logger = loggerModulu;
logger.info('Sunucu başlatılıyor...');
logger.success('Veritabanı bağlantısı kuruldu');
logger.warn('Bellek kullanımı %80 üzerinde');
logger.error('API yanıt vermedi, tekrar deneniyor');

// ---- Pratik örnek: config modülü ----
const configModulu = (function() {
    const ortam = process.env.NODE_ENV || 'development';

    const ayarlar = {
        development: {
            port: 3000,
            veritabani: 'mongodb://localhost/dev_db',
            debug: true,
            logSeviyesi: 'debug'
        },
        production: {
            port: process.env.PORT || 8080,
            veritabani: process.env.DATABASE_URL,
            debug: false,
            logSeviyesi: 'error'
        },
        test: {
            port: 3001,
            veritabani: 'mongodb://localhost/test_db',
            debug: true,
            logSeviyesi: 'warn'
        }
    };

    // module.exports = ayarlar[ortam];
    return ayarlar[ortam];
})();

console.log('\nConfig:', configModulu);

Modül sistemi Node.js'in bel kemiğidir. Her dosyayı bir modül olarak düşünün, sadece gerekli olanı dışa aktarın ve iç detayları gizleyin. Bu encapsulation prensibi kodunuzu hem daha güvenli hem de daha bakımı kolay yapar. Sonraki konuda ES Modules'ı göreceğiz, karşılaştırma yapabilirsiniz. Kolay gelsin.
 

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)

Geri
Üst