Bu ders için video bulunmamaktadır.

Bu derse başlamak veya ilerlemenizi kaydetmek için lütfen giriş yapın veya kayıt olun.

Ders İçeriği

Node.js Modül Sistemi

Node.js'in en güçlü özelliklerinden biri modül sistemidir. Modüller, kodunuzu organize etmenizi, yeniden kullanılabilir parçalar oluşturmanızı ve büyük projeleri yönetilebilir hale getirmenizi sağlar. Node.js'te iki ana modül sistemi vardır: CommonJS ve ES Modules.

CommonJS Modülleri

CommonJS, Node.js'in varsayılan modül sistemidir. Bu sistemde require() fonksiyonu ile modülleri içe aktarır, module.exports veya exports ile dışa aktarırız.

Modül Oluşturma:

// math.js
function topla(a, b) {
    return a + b;
}

function cikar(a, b) {
    return a - b;
}

function carp(a, b) {
    return a * b;
}

function bol(a, b) {
    if (b === 0) {
        throw new Error('Sıfıra bölme hatası!');
    }
    return a / b;
}

// Fonksiyonları dışa aktar
module.exports = {
    topla,
    cikar,
    carp,
    bol
};

// Alternatif yazım
// exports.topla = topla;
// exports.cikar = cikar;

Modül Kullanma:

// app.js
const math = require('./math');

console.log('5 + 3 =', math.topla(5, 3));
console.log('10 - 4 =', math.cikar(10, 4));
console.log('6 * 7 =', math.carp(6, 7));
console.log('15 / 3 =', math.bol(15, 3));

// Destructuring ile belirli fonksiyonları al
const { topla, carp } = require('./math');
console.log('Destructuring ile:', topla(2, 3), carp(4, 5));

ES Modules (ECMAScript Modules)

ES Modules, modern JavaScript'in standart modül sistemidir. Node.js 12+ sürümlerinde desteklenir. Bu sistemde import ve export anahtar kelimelerini kullanırız.

ES Modules Kullanımı:

// math.mjs veya package.json'da "type": "module" ile math.js
export function topla(a, b) {
    return a + b;
}

export function cikar(a, b) {
    return a - b;
}

// Default export
export default function carp(a, b) {
    return a * b;
}

// app.mjs
import carp, { topla, cikar } from './math.mjs';

console.log('Toplama:', topla(5, 3));
console.log('Çıkarma:', cikar(10, 4));
console.log('Çarpma:', carp(6, 7));

Yerleşik (Built-in) Modüller

Node.js, birçok yerleşik modül ile birlikte gelir. Bu modüller Node.js kurulumu ile birlikte otomatik olarak kullanılabilir hale gelir:

// Dosya sistemi modülü
const fs = require('fs');

// HTTP modülü
const http = require('http');

// Path modülü
const path = require('path');

// OS modülü
const os = require('os');

// Crypto modülü
const crypto = require('crypto');

// URL modülü
const url = require('url');

// Sistem bilgilerini göster
console.log('İşletim Sistemi:', os.platform());
console.log('Mimari:', os.arch());
console.log('Toplam Bellek:', Math.round(os.totalmem() / 1024 / 1024), 'MB');
console.log('Boş Bellek:', Math.round(os.freemem() / 1024 / 1024), 'MB');

NPM ve Paket Yönetimi

NPM (Node Package Manager), Node.js ekosisteminin kalbidir. Milyonlarca JavaScript paketi barındıran dünyanın en büyük yazılım kütüphanesi deposudur. NPM ile üçüncü taraf kütüphaneleri kolayca projelerinize ekleyebilirsiniz.

Proje Başlatma

Yeni bir Node.js projesi başlatmak için npm init komutunu kullanırız:

# İnteraktif proje oluşturma
npm init

# Varsayılan ayarlarla hızlı oluşturma
npm init -y

# Belirli bir template ile oluşturma
npm init @scope/template-name

Bu komut bir package.json dosyası oluşturur:

{
  "name": "nodejs-projesi",
  "version": "1.0.0",
  "description": "Node.js öğrenme projesi",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "dev": "nodemon index.js",
    "test": "jest"
  },
  "keywords": ["nodejs", "javascript", "backend"],
  "author": "Adınız Soyadınız",
  "license": "MIT",
  "dependencies": {},
  "devDependencies": {}
}

Paket Kurulumu ve Yönetimi

NPM ile paket kurma işlemleri:

# Üretim bağımlılığı kurma
npm install express
npm install lodash moment

# Geliştirme bağımlılığı kurma
npm install --save-dev nodemon jest eslint

# Global kurulum
npm install -g nodemon typescript

# Belirli sürüm kurma
npm install express@4.18.0

# Tüm bağımlılıkları kurma
npm install

# Paket güncelleme
npm update
npm update express

# Paket kaldırma
npm uninstall express
npm uninstall --save-dev nodemon

Package.json Scripts

Scripts bölümü, projede sık kullanılan komutları tanımlamanızı sağlar:

{
  "scripts": {
    "start": "node server.js",
    "dev": "nodemon server.js",
    "test": "jest",
    "test:watch": "jest --watch",
    "build": "webpack --mode production",
    "lint": "eslint .",
    "lint:fix": "eslint . --fix",
    "clean": "rm -rf dist/",
    "deploy": "npm run build && npm run test && git push"
  }
}

Bu scriptleri çalıştırmak için:

npm run dev
npm run test
npm start  # "start" için "run" gerekli değil
npm test   # "test" için "run" gerekli değil

Asenkron Programlama

Node.js'in en önemli özelliklerinden biri asenkron programlama desteğidir. Bu, uzun süren işlemlerin programın geri kalanını bloklamasını önler ve yüksek performans sağlar.

Callback Fonksiyonları

Callback'ler, asenkron işlemler tamamlandığında çağrılan fonksiyonlardır:

const fs = require('fs');

// Asenkron dosya okuma
fs.readFile('dosya.txt', 'utf8', (err, data) => {
    if (err) {
        console.error('Dosya okuma hatası:', err);
        return;
    }
    console.log('Dosya içeriği:', data);
});

console.log('Bu mesaj dosya okunmadan önce görünecek');

// Callback Hell örneği
fs.readFile('dosya1.txt', 'utf8', (err1, data1) => {
    if (err1) throw err1;
    
    fs.readFile('dosya2.txt', 'utf8', (err2, data2) => {
        if (err2) throw err2;
        
        fs.readFile('dosya3.txt', 'utf8', (err3, data3) => {
            if (err3) throw err3;
            
            console.log('Tüm dosyalar okundu');
            // Bu yapı "Callback Hell" olarak bilinir
        });
    });
});

Promise'ler

Promise'ler, callback hell problemini çözmek için geliştirilmiştir:

const fs = require('fs').promises;

// Promise ile dosya okuma
fs.readFile('dosya.txt', 'utf8')
    .then(data => {
        console.log('Dosya içeriği:', data);
        return fs.readFile('dosya2.txt', 'utf8');
    })
    .then(data2 => {
        console.log('İkinci dosya:', data2);
    })
    .catch(err => {
        console.error('Hata:', err);
    });

// Promise oluşturma
function bekle(ms) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(`${ms} milisaniye beklendi`);
        }, ms);
    });
}

bekle(2000)
    .then(mesaj => console.log(mesaj))
    .catch(err => console.error(err));

Async/Await

Async/await, Promise'leri daha okunabilir hale getirir:

const fs = require('fs').promises;

async function dosyalariOku() {
    try {
        const data1 = await fs.readFile('dosya1.txt', 'utf8');
        console.log('Birinci dosya:', data1);
        
        const data2 = await fs.readFile('dosya2.txt', 'utf8');
        console.log('İkinci dosya:', data2);
        
        const data3 = await fs.readFile('dosya3.txt', 'utf8');
        console.log('Üçüncü dosya:', data3);
        
        return 'Tüm dosyalar başarıyla okundu';
    } catch (error) {
        console.error('Dosya okuma hatası:', error);
        throw error;
    }
}

// Async fonksiyonu çağırma
dosyalariOku()
    .then(sonuc => console.log(sonuc))
    .catch(err => console.error('Ana hata:', err));

// Paralel işlemler
async function parallelOkuma() {
    try {
        const [data1, data2, data3] = await Promise.all([
            fs.readFile('dosya1.txt', 'utf8'),
            fs.readFile('dosya2.txt', 'utf8'),
            fs.readFile('dosya3.txt', 'utf8')
        ]);
        
        console.log('Tüm dosyalar paralel olarak okundu');
        return { data1, data2, data3 };
    } catch (error) {
        console.error('Paralel okuma hatası:', error);
    }
}

Olay Tabanlı Programlama (Event-Driven Programming)

Node.js, olay tabanlı bir mimari kullanır. Bu yaklaşımda, belirli olaylar gerçekleştiğinde ilgili fonksiyonlar (event listener'lar) çalıştırılır.

EventEmitter Sınıfı

Node.js'in events modülü, olay tabanlı programlama için EventEmitter sınıfını sağlar:

const EventEmitter = require('events');

// EventEmitter örneği oluştur
const myEmitter = new EventEmitter();

// Olay dinleyicisi ekle
myEmitter.on('mesaj', (kullanici, mesaj) => {
    console.log(`${kullanici}: ${mesaj}`);
});

myEmitter.on('hata', (hata) => {
    console.error('Hata oluştu:', hata);
});

// Tek seferlik dinleyici
myEmitter.once('baslangic', () => {
    console.log('Uygulama başlatıldı (sadece bir kez çalışır)');
});

// Olay tetikleme
myEmitter.emit('baslangic');
myEmitter.emit('mesaj', 'Ali', 'Merhaba dünya!');
myEmitter.emit('mesaj', 'Ayşe', 'Node.js harika!');
myEmitter.emit('hata', new Error('Test hatası'));

Özel EventEmitter Sınıfı Oluşturma

Kendi olay tabanlı sınıflarınızı oluşturabilirsiniz:

const EventEmitter = require('events');

class ChatOdasi extends EventEmitter {
    constructor(oda_adi) {
        super();
        this.oda_adi = oda_adi;
        this.kullanicilar = [];
    }
    
    kullaniciEkle(kullanici) {
        this.kullanicilar.push(kullanici);
        this.emit('kullanici_katildi', kullanici);
    }
    
    kullaniciCikar(kullanici) {
        const index = this.kullanicilar.indexOf(kullanici);
        if (index > -1) {
            this.kullanicilar.splice(index, 1);
            this.emit('kullanici_ayrildi', kullanici);
        }
    }
    
    mesajGonder(kullanici, mesaj) {
        if (this.kullanicilar.includes(kullanici)) {
            this.emit('yeni_mesaj', kullanici, mesaj);
        } else {
            this.emit('hata', new Error('Kullanıcı odada değil'));
        }
    }
}

// Chat odası kullanımı
const genel_oda = new ChatOdasi('Genel');

genel_oda.on('kullanici_katildi', (kullanici) => {
    console.log(`${kullanici} odaya katıldı`);
});

genel_oda.on('kullanici_ayrildi', (kullanici) => {
    console.log(`${kullanici} odadan ayrıldı`);
});

genel_oda.on('yeni_mesaj', (kullanici, mesaj) => {
    console.log(`[${genel_oda.oda_adi}] ${kullanici}: ${mesaj}`);
});

genel_oda.on('hata', (hata) => {
    console.error('Chat hatası:', hata.message);
});

// Olayları tetikle
genel_oda.kullaniciEkle('Ali');
genel_oda.kullaniciEkle('Ayşe');
genel_oda.mesajGonder('Ali', 'Merhaba herkese!');
genel_oda.mesajGonder('Ayşe', 'Selam Ali!');
genel_oda.kullaniciCikar('Ali');

Stream'ler ve Olaylar

Node.js'teki stream'ler de EventEmitter'dan türetilmiştir:

const fs = require('fs');

// Dosya okuma stream'i
const readStream = fs.createReadStream('buyuk_dosya.txt', { encoding: 'utf8' });

readStream.on('data', (chunk) => {
    console.log('Veri parçası alındı:', chunk.length, 'karakter');
});

readStream.on('end', () => {
    console.log('Dosya okuma tamamlandı');
});

readStream.on('error', (err) => {
    console.error('Okuma hatası:', err);
});

// HTTP sunucusu da olay tabanlıdır
const http = require('http');

const server = http.createServer();

server.on('request', (req, res) => {
    console.log('Yeni istek:', req.method, req.url);
    res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
    res.end('Merhaba Node.js!');
});

server.on('listening', () => {
    console.log('Sunucu dinlemeye başladı');
});

server.on('error', (err) => {
    console.error('Sunucu hatası:', err);
});

server.listen(3000);

Error Handling (Hata Yönetimi)

Node.js'te hata yönetimi kritik öneme sahiptir. Doğru hata yönetimi, uygulamanızın kararlı çalışmasını sağlar.

Try-Catch Blokları

// Senkron hata yönetimi
try {
    const sonuc = JSON.parse('geçersiz json');
    console.log(sonuc);
} catch (error) {
    console.error('JSON parse hatası:', error.message);
}

// Async/await ile hata yönetimi
async function dosyaIslemleri() {
    try {
        const data = await fs.readFile('olmayan_dosya.txt', 'utf8');
        console.log(data);
    } catch (error) {
        console.error('Dosya okuma hatası:', error.message);
    }
}

Process Event'leri

// Yakalanmamış exception'ları yakala
process.on('uncaughtException', (error) => {
    console.error('Yakalanmamış hata:', error);
    process.exit(1);
});

// Yakalanmamış promise rejection'ları yakala
process.on('unhandledRejection', (reason, promise) => {
    console.error('Yakalanmamış promise rejection:', reason);
    process.exit(1);
});