Kod Kalitesi: ESLint ve Prettier
Neden Otomatik Kod Kalitesi?
Bir ekipte beş geliştirici olduğunu düşün. Biri tab kullanıyor, diğeri boşluk. Biri tek tırnak seviyor, diğeri çift tırnak. Biri fonksiyon sonuna noktalı virgül koyuyor, diğeri koymuyor. Kodlar bir araya geldiğinde tutarsız bir karmaşa oluşuyor — okunması zor, review'u sancılı, merge conflict'leri acı verici.
Daha kötüsü: biri == kullanıyor (=== yerine), biri kullanılmayan değişkenleri silmek yerine bırakıyor, biri any tipini rahatça kullanıyor. Bunlar sadece stil sorunu değil — hata kaynağı.
Analoji: Bir hastanedeki hijyen protokolünü düşün. Her doktor kendi kafasına göre ellerini yıkasa, bazısı yıkamasa, bazısı sadece su ile yıkasa ne olur? Enfeksiyon kaçınılmaz. Otomatik dezenfeksiyon istasyonları bu sorunu çözer — herkes aynı standart prosedürü uygular, düşünmesine gerek kalmaz. ESLint ve Prettier, kodunun "hijyen protokolü"dür.
Bu sorunların çözümü: otomatik araçlar. İnsan gözüyle her kod satırını denetlemek yerine, araçların otomatik olarak:
Hataları tespit etmesini (ESLint)
Formatlamayı düzeltmesini (Prettier)
Commit öncesi kontrol yapmasını (Husky + lint-staged)
Bu üçlü birlikte çalıştığında ekibin kod kalitesi otopilotta olur.
ESLint: Kod Kalite Bekçisi
ESLint, JavaScript/TypeScript kodunu statik olarak analiz eder ve potansiyel hataları, kötü pratikleri, stil ihlallerini tespit eder. Kodu çalıştırmadan, sadece okuyarak sorunları bulur.
Bir editörün (düzeltmen) yazını okuması gibi düşün: yazım hatalarını, dilbilgisi sorunlarını, tutarsızlıkları işaretler — ama içeriği değiştirmez, sana bildirir.
Kurulum
# ESLint 9+ (Flat Config)
npm install -D eslint @eslint/js typescript-eslint
# TypeScript desteği
npm install -D @typescript-eslint/parser @typescript-eslint/eslint-pluginYapılandırma (Flat Config — ESLint 9+)
ESLint 9 ile birlikte yeni "flat config" formatına geçildi. Eski .eslintrc yerine eslint.config.js kullanılır:
// eslint.config.js
import eslint from "@eslint/js";
import tseslint from "typescript-eslint";
export default tseslint.config(
// Temel önerilen kurallar
eslint.configs.recommended,
// TypeScript önerilen kurallar
...tseslint.configs.recommended,
// Özel kurallar
{
rules: {
// Hata önleme
"no-unused-vars": "off", // TS versiyonunu kullan
"@typescript-eslint/no-unused-vars": ["error", {
argsIgnorePattern: "^_", // _param gibi olanları yoksay
varsIgnorePattern: "^_",
}],
"@typescript-eslint/no-explicit-any": "warn",
"no-console": ["warn", { allow: ["warn", "error"] }],
// Best practice
"eqeqeq": ["error", "always"], // === kullan
"no-var": "error", // var kullanma
"prefer-const": "error", // Değişmeyen let → const
"no-throw-literal": "error", // throw "hata" değil, throw new Error
"curly": ["error", "multi-line"], // if sonrası {} zorunlu
// TypeScript specific
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-non-null-assertion": "warn",
},
},
// Test dosyaları için gevşetme
{
files: ["**/*.test.ts", "**/*.spec.ts"],
rules: {
"@typescript-eslint/no-explicit-any": "off",
"no-console": "off",
},
},
// İgnore patterns
{
ignores: ["dist/", "node_modules/", "coverage/"],
}
);ESLint 9 vs Eski Sürümler
ESLint 9 öncesinde .eslintrc.json veya .eslintrc.js kullanılırdı. İki format arasındaki farkları bilmek önemli çünkü birçok tutorial hâlâ eski formatta:
// ❌ ESKİ FORMAT (.eslintrc.js) — ESLint 8 ve altı
module.exports = {
parser: "@typescript-eslint/parser",
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
],
plugins: ["@typescript-eslint"],
rules: {
"no-var": "error",
},
};
// ✅ YENİ FORMAT (eslint.config.js) — ESLint 9+
// Flat config: daha basit, daha anlaşılır, cascade yok
import eslint from "@eslint/js";
import tseslint from "typescript-eslint";
export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.recommended,
{
rules: {
"no-var": "error",
},
}
);
// Farklar:
// 1. extends/plugins yerine doğrudan import
// 2. JSON yerine JavaScript (tip güvenliği, otomatik tamamlama)
// 3. Dosya bazlı override daha sezgisel
// 4. Kaskad (cascade) yok — yukarıdan aşağı, basit💡 İpucu: Yeni projelerde her zaman ESLint 9+ flat config kullan. Eski projelerdeki
.eslintrcdosyasını flat config'e migrate etmek içinnpx @eslint/migrate-config .eslintrc.jsonkomutunu kullanabilirsin.
ESLint Kuralları Derinlemesine
Kurallar üç seviyede ayarlanır:
"off"veya0— Kural kapalı"warn"veya1— Uyarı (sarı)"error"veya2— Hata (kırmızı, build'i durdurur)
// Örnek: ESLint ne yakalar?
// ❌ no-unused-vars: Kullanılmayan değişken
const unused = "silinmeli"; // eslint: error
// ❌ eqeqeq: == yerine === kullan
if (x == null) { } // eslint: error, === kullan
// ❌ no-var: var kullanma
var oldStyle = true; // eslint: error, let/const kullan
// ❌ no-console: Production'da console.log olmamalı
console.log("debug"); // eslint: warn
// ❌ @typescript-eslint/no-explicit-any: any kullanma
function process(data: any) { } // eslint: warn
// ✅ Düzeltilmiş versiyonlar
const _unused = "underscore prefix ile OK";
if (x === null) { }
const modernStyle = true;
console.error("Hata!"); // error/warn OK
function process(data: unknown) { }Önemli ESLint Kuralları Rehberi
// === Hata Önleme Kuralları ===
// no-undef: Tanımlanmamış değişken kullanımı
// konsol.log("test"); // ❌ konsol tanımlı değil (typo)
// no-dupe-keys: Nesne'de tekrar eden anahtar
// const obj = { a: 1, b: 2, a: 3 }; // ❌ 'a' iki kez var
// no-unreachable: return sonrası erişilemez kod
// function example() { return 1; console.log("asla"); } // ❌
// no-constant-condition: Sabit koşul
// if (true) { } // ❌ Her zaman true — mantık hatası olabilir
// === Güvenlik Kuralları ===
// no-eval: eval() kullanımını yasakla
// eval("alert('XSS riski!')"); // ❌ Güvenlik açığı
// no-implied-eval: setTimeout/setInterval'da string
// setTimeout("alert('hello')", 100); // ❌ eval gibi çalışır
// setTimeout(() => alert("hello"), 100); // ✅ Fonksiyon kullan
// === TypeScript Özel Kuralları ===
// @typescript-eslint/no-floating-promises: await unutma
// async function loadData() {
// fetchData(); // ❌ await yok — hata sessizce yutulur
// await fetchData(); // ✅
// }
// @typescript-eslint/no-misused-promises: Promise'i yanlış kullanma
// const isValid = items.filter(async item => { // ❌ filter async beklemez
// return await validateItem(item);
// });ESLint Çalıştırma
# Tüm dosyaları kontrol et
npx eslint src/
# Otomatik düzeltilebilenleri düzelt
npx eslint src/ --fix
# Belirli dosya
npx eslint src/utils/math.ts
# Belirli kuralı devre dışı bırakarak çalıştır
npx eslint src/ --rule '{"no-console": "off"}'
# Cache kullanarak hızlandır (sadece değişen dosyaları kontrol et)
npx eslint src/ --cache
# package.json scripts
{
"scripts": {
"lint": "eslint src/",
"lint:fix": "eslint src/ --fix",
"lint:cache": "eslint src/ --cache"
}
}💡 İpucu: VS Code'da ESLint extension'ı yükle — dosya kaydedildiğinde otomatik düzeltme yapabilir. Settings:
"editor.codeActionsOnSave": { "source.fixAll.eslint": "always" }
Inline Kuralları Kapatma/Açma
Bazen belirli satırlarda kuralı geçici olarak kapatman gerekir. Ama bunu bilinçli ve açıklamalı yap:
// Tek satır için kapat
// eslint-disable-next-line no-console
console.log("Bu bir debug mesajı");
// Belirli kural için kapat (açıklamalı — best practice)
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Legacy API tipsiz
const data: any = legacyApi.getData();
// Blok için kapat
/* eslint-disable no-console */
console.log("log 1");
console.log("log 2");
console.log("log 3");
/* eslint-enable no-console */
// Dosyanın tamamı için (dosyanın en üstünde)
/* eslint-disable @typescript-eslint/no-explicit-any */
// Bu dosya legacy API wrapper — any kullanımı kaçınılmaz⚠️ Dikkat: eslint-disable kullanımını minimumda tut. Eğer bir projede çok fazla disable varsa, kuralı ya düzelt ya da kaldır. Disable, "bu kuralı biliyorum ama bilinçli olarak ihlal ediyorum" demektir — sürekli kullanılmamalıdır.
Prettier: Kod Formatlayıcı
ESLint hataları tespit eder ama formatlamaya sınırlı müdahale eder. Prettier ise kodun görünümünü tamamen düzeltir: girintileme, tırnak stili, satır uzunluğu, noktalı virgül, parantez konumu... Tüm format kararlarını alır, tartışmaya son verir.
Bir terzi gibi düşün: kumaşı (kodu) alır, düzgünce ütüler, temiz katlar — içeriğine dokunmaz, sadece görünümünü düzeltir.
Prettier'ın Felsefesi: Opinionated
Prettier'ın ayırt edici özelliği opinionated (fikirli/katı) olmasıdır. Çok az yapılandırma seçeneği sunar. Bu bir dezavantaj değil, en büyük avantajı:
ESLint: 200+ format kuralı, her biri tartışılabilir
→ Ekip: "Tab mı space mi?" "2 mi 4 mü?" tartışması
Prettier: ~10 ayar seçeneği, geri kalan sabit
→ Ekip: "Prettier ne diyorsa o." tartışma bitti ✅Kurulum
npm install -D prettier
# ESLint ile çakışmaları engelle
npm install -D eslint-config-prettierYapılandırma
// .prettierrc
{
"semi": true,
"singleQuote": false,
"tabWidth": 2,
"trailingComma": "all",
"printWidth": 100,
"bracketSpacing": true,
"arrowParens": "always",
"endOfLine": "lf"
}Her ayarın anlamı:
semi: true → Satır sonunda noktalı virgül (;) koy
singleQuote: false → Çift tırnak kullan ("hello")
tabWidth: 2 → 2 boşluk girintileme
trailingComma: "all" → Son elemandan sonra da virgül koy
printWidth: 100 → Satır uzunluğu limiti (100 karakter)
bracketSpacing: true → Nesne literallerinde boşluk ({ a: 1 })
arrowParens: "always"→ Arrow function tek parametrede de parantez: (x) => x
endOfLine: "lf" → Unix satır sonu (\n)// .prettierignore
dist/
node_modules/
coverage/
*.min.js
pnpm-lock.yamlPrettier Öncesi/Sonrası
// ❌ Önce: Tutarsız format
const user={name:"Ali",age:25,
email: 'ali@test.com',
preferences: {theme: 'dark',language:"tr"
}
}
function greet(name){
if(name) {return `Merhaba ${name}`}
else{
return "Merhaba Misafir"
}
}
// ✅ Sonra (Prettier uygulandıktan sonra): Tutarlı format
const user = {
name: "Ali",
age: 25,
email: "ali@test.com",
preferences: { theme: "dark", language: "tr" },
};
function greet(name) {
if (name) {
return `Merhaba ${name}`;
} else {
return "Merhaba Misafir";
}
}Prettier Çalıştırma
# Kontrol et (değiştirmeden)
npx prettier --check src/
# Düzelt
npx prettier --write src/
# Tek dosya
npx prettier --write src/utils/math.ts
# Belirli dosya türleri
npx prettier --write "src/**/*.{ts,tsx,css,json}"ESLint + Prettier Entegrasyonu
ESLint ve Prettier'ın çakışan kuralları olabilir. eslint-config-prettier bu çakışmaları engeller:
// eslint.config.js — Prettier entegrasyonu
import eslint from "@eslint/js";
import tseslint from "typescript-eslint";
import prettier from "eslint-config-prettier";
export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.recommended,
// ⚠️ Prettier'ı EN SONA koy — çakışan ESLint kurallarını kapatır
prettier,
{
rules: {
// Format kurallarını ESLint'te TANIMLA — Prettier halledecek
// "semi": ... ← BUNU YAPMA
// "quotes": ... ← BUNU YAPMA
// Sadece mantık kurallarını ESLint'te tanımla
"eqeqeq": "error",
"no-var": "error",
"prefer-const": "error",
},
}
);Kural: ESLint = mantık ve kalite kuralları. Prettier = format kuralları. İkisini karıştırma.
💡 İpucu: Eski projelerde
eslint-plugin-prettierkullanıldığını görebilirsin — bu, Prettier'ı ESLint kuralı olarak çalıştırır. Artık önerilmiyor. Modern yaklaşım: ESLint ve Prettier'ı ayrı ayrı çalıştır,eslint-config-prettierile çakışmaları engelle.
Husky + lint-staged: Commit Öncesi Kalkan
ESLint ve Prettier harika araçlar ama kullanılmadıkça işe yaramazlar. Geliştirici eslint veya prettier çalıştırmayı unutabilir. Sonuç: hatalı, formatlanmamış kod repo'ya girer.
Çözüm: Git hook'ları ile commit öncesi otomatik kontrol. Kapıdaki güvenlik noktası gibi — çıkmadan önce kontrol yapılır.
Git Hook'ları Nedir?
Git, belirli olaylarda (commit, push, merge) otomatik script çalıştırabilir. Bu scriptlere hook denir:
pre-commit → Commit ÖNCESI çalışır (lint, format, test)
commit-msg → Commit mesajını KONTROL eder
pre-push → Push ÖNCESI çalışır (testler)
post-merge → Merge SONRASI çalışır (npm install)Husky: Git Hook Yöneticisi
# Husky kurulumu
npm install -D husky
# Git hooks klasörünü oluştur
npx husky initBu komut .husky/pre-commit dosyası oluşturur. Her git commit komutu çalıştırılmadan önce bu script çalışır.
lint-staged: Sadece Değişen Dosyaları Kontrol Et
Tüm projeyi her commit'te kontrol etmek yavaş. lint-staged sadece staging area'daki (commit edilecek) dosyaları kontrol eder:
npm install -D lint-staged// package.json
{
"lint-staged": {
"*.{ts,tsx,js,jsx}": [
"eslint --fix",
"prettier --write"
],
"*.{json,md,css,scss}": [
"prettier --write"
]
}
}# .husky/pre-commit
npx lint-stagedAkış
git add src/math.ts ← Dosya staging'e eklendi
git commit -m "fix" ← Commit denemesi
↓
Husky: pre-commit hook tetiklendi
↓
lint-staged: sadece math.ts için:
1. eslint --fix math.ts ← Lint hatası varsa commit durur!
2. prettier --write math.ts ← Format düzeltilir
↓
Hata yoksa: Commit başarılı ✅
Hata varsa: Commit engellendi ❌ (geliştirici düzeltmeli)# Örnek senaryo
$ git commit -m "kullanıcı validasyonu eklendi"
⧗ Preparing lint-staged...
❯ Running tasks for *.{ts,tsx,js,jsx}...
✖ eslint --fix:
/src/userValidator.ts
3:7 error 'unused' is assigned but never used @typescript-eslint/no-unused-vars
7:5 error Unexpected 'var', use 'let' or 'const' no-var
✖ lint-staged failed! Fix the errors and try again.Geliştirici hataları düzeltmeden commit yapamaz. Bu sayede repo'ya hatalı kod girmez.
commitlint: Commit Mesajı Standardı
npm install -D @commitlint/cli @commitlint/config-conventional// commitlint.config.js
export default {
extends: ["@commitlint/config-conventional"],
};
// Geçerli commit mesajları:
// feat: kullanıcı kaydı eklendi
// fix: login hatası düzeltildi
// docs: README güncellendi
// style: format düzeltmesi
// refactor: UserService yeniden yapılandırıldı
// test: cart testleri eklendi
// chore: dependencies güncellendi# .husky/commit-msg
npx --no -- commitlint --edit ${1}# ❌ Kötü commit mesajı → engellenir
$ git commit -m "fix"
⧗ input: fix
✖ subject may not be empty [subject-empty]
✖ type may not be empty [type-empty]
# ✅ İyi commit mesajı → kabul edilir
$ git commit -m "fix: login sayfasında şifre validasyonu düzeltildi"Conventional Commits Tipleri
feat: → Yeni özellik
fix: → Hata düzeltmesi
docs: → Dokümantasyon değişikliği
style: → Format değişikliği (boşluk, noktalı virgül)
refactor: → Kod yeniden yapılandırma (özellik/hata değişikliği yok)
test: → Test ekleme/düzeltme
chore: → Build, CI, dependency gibi bakım işleri
perf: → Performans iyileştirmesi
ci: → CI/CD pipeline değişikliği
Scope ekleyebilirsin:
feat(auth): Google OAuth eklendi
fix(cart): ürün silme hatası düzeltildi
refactor(api): fetch client abstractionCI/CD Entegrasyonu
Husky yerel geliştirme ortamında çalışır. Ama biri --no-verify ile commit'i bypass edebilir. CI/CD pipeline'ı son savunma hattıdır:
GitHub Actions Örneği
# .github/workflows/quality.yml
name: Code Quality
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
lint-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: "npm"
- run: npm ci # Lock dosyasına sadık kur
- run: npm run lint # ESLint kontrolü
- run: npx prettier --check src/ # Format kontrolü
- run: npm run type-check # TypeScript tip kontrolü (tsc --noEmit)
- run: npm test # TestlerBu pipeline sayesinde:
PR açıldığında otomatik kontrol
Lint hatası varsa merge engellenebilir
Tüm ekip aynı standartlara uymak zorunda
💡 İpucu: GitHub'da branch protection rules ile "Required status checks" ayarlayarak, bu CI kontrollerini geçmeden merge'i engelleyebilirsin. Bu, kalite kontrol zincirinin en güçlü halkası.
Editor Entegrasyonu
VS Code Ayarları
// .vscode/settings.json — Proje seviyesinde
{
// Kayıt sırasında format
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
// ESLint otomatik düzeltme
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "always",
"source.organizeImports": "always"
},
// Dosya türüne göre formatter
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
// TypeScript ayarları
"typescript.preferences.importModuleSpecifier": "relative",
"typescript.updateImportsOnFileMove.enabled": "always"
}// .vscode/extensions.json — Önerilen extension'lar
{
"recommendations": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"streetsidesoftware.code-spell-checker",
"usernamehw.errorlens",
"gruntfuggly.todo-tree"
]
}EditorConfig: Editörler Arası Uyum
Prettier kullansan bile, VS Code dışında editör kullanan ekip üyeleri için .editorconfig faydalıdır:
# .editorconfig
root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[Makefile]
indent_style = tabSıfırdan Tam Kurulum Rehberi
Yeni bir projeye tüm kalite araçlarını kurmak için adım adım:
# 1. Proje oluştur
mkdir my-project && cd my-project
npm init -y
# 2. TypeScript
npm install -D typescript
npx tsc --init
# 3. ESLint + TypeScript
npm install -D eslint @eslint/js typescript-eslint eslint-config-prettier
# 4. Prettier
npm install -D prettier
# 5. Husky + lint-staged + commitlint
npm install -D husky lint-staged
npm install -D @commitlint/cli @commitlint/config-conventional
npx husky init
# 6. Yapılandır
echo 'npx lint-staged' > .husky/pre-commit
echo 'npx --no -- commitlint --edit ${1}' > .husky/commit-msg// package.json — eklenecek scripts ve lint-staged
{
"scripts": {
"dev": "tsx watch src/index.ts",
"build": "tsc",
"lint": "eslint src/",
"lint:fix": "eslint src/ --fix",
"format": "prettier --write src/",
"format:check": "prettier --check src/",
"type-check": "tsc --noEmit",
"quality": "npm run lint && npm run format:check && npm run type-check",
"test": "jest"
},
"lint-staged": {
"*.{ts,tsx,js,jsx}": ["eslint --fix", "prettier --write"],
"*.{json,md,css}": ["prettier --write"]
}
}Oluşturulacak yapılandırma dosyaları:
my-project/
├── eslint.config.js ← ESLint flat config
├── .prettierrc ← Prettier ayarları
├── .prettierignore ← Prettier yoksayma
├── .editorconfig ← Editör ayarları
├── commitlint.config.js ← Commit mesajı kuralları
├── tsconfig.json ← TypeScript ayarları
├── .vscode/
│ ├── settings.json ← VS Code proje ayarları
│ └── extensions.json ← Önerilen extension'lar
├── .husky/
│ ├── pre-commit ← npx lint-staged
│ └── commit-msg ← commitlint
└── src/
└── index.tsGerçek Dünya: Kalite Kontrol Katmanları
Her şey kurulduktan sonra günlük iş akışı şöyle olur:
Katman 1: YAZARKEN
├── VS Code ESLint extension → Anında kırmızı/sarı altı çizili
├── VS Code Prettier → Kayıt sırasında otomatik format
└── TypeScript → Tip hataları anında görünür
Katman 2: COMMIT EDERKEN
├── Husky pre-commit hook tetiklenir
├── lint-staged: değişen dosyalarda ESLint + Prettier çalışır
├── commitlint: commit mesajı formatını kontrol eder
└── Hata varsa commit engellenir
Katman 3: PUSH/PR SIRASINDA
├── GitHub Actions / GitLab CI tetiklenir
├── Tüm dosyalarda lint, format, tip kontrolü çalışır
├── Testler çalışır
└── Başarısızsa merge engellenir
Katman 4: PRODUCTION
├── Build sırasında TypeScript derleme
├── Bundler optimizasyonları
└── Source map ile debugGeliştirici perspektifinden neredeyse görünmez — arka planda çalışır, sadece hata yaptığında kendini gösterir. Bu zero-friction quality yaklaşımıdır.
Yaygın Hatalar
1. ESLint ve Prettier Çakışması
// ❌ ESLint'te format kuralı + Prettier = çatışma
// ESLint: "tek tırnak kullan" vs Prettier: "çift tırnak kullan"
// Sonuç: Her kayıtta dosya değişir, ESLint hata verir, Prettier düzeltir...
// ✅ Çözüm: eslint-config-prettier kullan — ESLint format kurallarını kapatır
// ESLint: mantık kuralları (eqeqeq, no-var, no-unused-vars)
// Prettier: format kuralları (quotes, semi, indentation)2. lint-staged Olmadan Husky Kullanmak
# ❌ Tüm projeyi kontrol eder — yavaş!
# .husky/pre-commit
npx eslint src/
# ✅ Sadece değişen dosyaları kontrol et — hızlı!
# .husky/pre-commit
npx lint-staged3. ESLint Kurallarını Devre Dışı Bırakma Alışkanlığı
// ❌ Her yerde disable — kuralın anlamı kalmıyor
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const data: any = fetchSomething();
// ✅ Gerçekten gerekiyorsa, nedenini açıkla
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- 3rd party API untyped
const data: any = legacyApi.getData();4. Prettier'ı Yanlış Yere Koymak
// ❌ eslint.config.js'de prettier EN SONA konmalı
export default tseslint.config(
prettier, // ❌ Başta — etkisiz!
eslint.configs.recommended,
...tseslint.configs.recommended,
);
// ✅ Doğru sıralama
export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.recommended,
prettier, // ✅ En sonda — format kurallarını override eder
);5. CI'da npm ci Yerine npm install Kullanmak
# ❌ CI/CD'de npm install — lock dosyası güncellenebilir
npm install && npm run lint
# ✅ CI/CD'de npm ci — lock dosyasına sadık kalır
npm ci && npm run lintÖzel ESLint Kuralı Yazma (İleri Seviye)
Projeye özel kurallar yazabilirsin. Örneğin, console.log yerine özel logger kullanmayı zorunlu kılan bir kural:
// eslint-rules/no-direct-console.js
export default {
meta: {
type: "suggestion",
docs: {
description: "console.log yerine Logger kullanımını zorla",
},
fixable: "code",
messages: {
useLogger: "console.{{ method }} yerine Logger.{{ method }} kullanın",
},
},
create(context) {
return {
MemberExpression(node) {
if (
node.object.name === "console" &&
["log", "warn", "error", "info"].includes(node.property.name)
) {
context.report({
node,
messageId: "useLogger",
data: { method: node.property.name },
fix(fixer) {
return fixer.replaceText(node.object, "Logger");
},
});
}
},
};
},
};
// eslint.config.js'de kullanım:
import noDirectConsole from "./eslint-rules/no-direct-console.js";
export default [
{
plugins: {
custom: { rules: { "no-direct-console": noDirectConsole } },
},
rules: {
"custom/no-direct-console": "error",
},
},
];Özet
ESLint: Kod kalitesi ve mantık hatalarını tespit eder.
===kullanımı, unused vars,anytipi gibi sorunları yakalar. ESLint 9+ flat config formatını kullan.Prettier: Kod formatını otomatik düzeltir. Tab/space, tırnak, noktalı virgül tartışmalarına son verir. Opinionated — az seçenek, tutarlı sonuç.
ESLint + Prettier: ESLint mantık kuralları, Prettier format kuralları.
eslint-config-prettierile çakışmayı engelle. Prettier her zaman config'in sonunda olmalı.Husky: Git hook'larını yönetir.
pre-commithook'u ile commit öncesi kontrol.commit-msghook'u ile commit mesajı standardı.lint-staged: Sadece commit edilecek dosyaları kontrol eder — hızlı ve odaklı. Tüm projeyi kontrol etmekten kaçın.
CI/CD: GitHub Actions veya GitLab CI ile push/PR'da otomatik kontrol.
npm ciile tutarlı kurulum.Editor entegrasyonu: VS Code'da kayıt sırasında otomatik format ve lint fix — sıfır sürtünme.
Tüm bu araçlar birlikte: yazmadan önce, yazarken, commit ederken ve CI'da — dört katmanlı kalite koruması sağlar.
AI Asistan
Sorularını yanıtlamaya hazır