Giriş
FreeCodeCamp, bir öğrenme platformundan çok daha fazlasıdır; binlerce katkıcıya ve milyonlarca satırlık JavaScript ve TypeScript koduna sahip, geniş bir açık kaynak kod tabanıdır. Böylesine karmaşık bir projenin yönetimi, gerilemeleri önlemek ve güvenilirliği sürdürmek için tutarlı mimari kalıplar, katı adlandırma kuralları ve kapsamlı testler gerektirir.
Bu makalede, FreeCodeCamp’ten derlenen en etkili kod inceleme kurallarını sunuyoruz. Her kural, özenli tasarım, tutarlı veri akışı ve sağlam hata yönetiminin büyük projelerin düzenli kalmasına nasıl yardımcı olabileceğini ve zaman içinde gözden kaçan hataların ortaya çıkma riskini nasıl azaltabileceğini göstermektedir.
Zorluklar
FreeCodeCamp’te, geniş JavaScript ve TypeScript kod tabanı ve binlerce katkıcı nedeniyle kod kalitesini korumak zorlu bir iştir. Tutarlı kalıpların, öngörülebilir veri akışının ve güvenilir işlevselliğin sağlanması, yapılandırılmış inceleme kuralları ve otomatik kontroller gerektirir.
Başlıca zorluklar arasında tutarsız kodlama kalıpları, birbirine sıkı sıkıya bağlı eski modüller, dengesiz test kapsamı, belgelerde zamanla meydana gelen sapmalar ve yüksek sayıda çekme isteği yer almaktadır.
Net standartlar, otomatik doğrulama ve titiz kod incelemesi, proje büyüdükçe kod tabanının bakımının kolay, istikrarlı ve ölçeklenebilir kalmasına yardımcı olur.
Bu kuralların önemi nedir?
Tutarlı kod inceleme kuralları, tek tip modül yapısı, adlandırma kuralları ve öngörülebilir veri akışlarını zorunlu kılarak bakım kolaylığını artırır; bu sayede testlerin güvenilirliği artar ve bağımlılıkların takibi kolaylaşır.
Ayrıca, girdi doğrulama, hata işleme ve kontrollü yan etkiler yoluyla güvenliği artırırken, yeni katkıcıların modül sorumluluklarını ve entegrasyon noktalarını hızlı bir şekilde anlamalarına yardımcı olarak katılım sürecini hızlandırırlar.
Bu kurallarla bağlam arasında bağlantı kurma
Bu kurallar, FreeCodeCamp’in depo ve çekme isteklerinden derlenmiştir ve istikrar ile bakım kolaylığını etkileyen, veri akışının belirsizliği, hata işleme eksikliği ve tutarsız testler gibi sıkça karşılaşılan sorunları yansıtmaktadır.
Her kural, somut bir tuzağı ortaya koyar, bunun performans, anlaşılırlık veya güvenilirlik üzerindeki etkisini açıklar ve ❌ kurallara uymayan ile ✅ kurallara uyan JavaScript veya TypeScript örneklerini içerir.
1. TypeScript’te her türlü aşırı kullanımdan kaçının
TypeScript'te herhangi bir tür kullanmaktan kaçının. Tür güvenliğini sağlamak ve çalışma zamanı hatalarını önlemek için değişkenler, işlev parametreleri ve dönüş değerleri için her zaman doğru ve açık türler tanımlayın.
❌ Uygun değil:
let userData: any = fetchUserData();✅ Uygunluk:
interface UserData {
id: string;
name: string;
email: string;
}
let userData: UserData = fetchUserData();Bunun önemi: "any" kullanımı, TypeScript'in tip denetimini devre dışı bırakır; bu da çalışma zamanı hatalarının ortaya çıkmasına neden olabilir ve kodun bakım kolaylığını ve güvenilirliğini azaltabilir. Açık tipler, kodu daha güvenli hale getirir ve diğer geliştiricilerin kodu anlamasını kolaylaştırır.
2. Kısaltmalar yerine açıklayıcı değişken adlarını tercih edin
Her zaman açık ve açıklayıcı değişken adları kullanın. Kodun anlamını belirsizleştiren kısaltmalardan veya anlaşılması zor adlardan kaçının.
❌ Uygun değil:
const usr = getUser();✅ Uygunluk:
const user = getUser();Bunun önemi: Açıklayıcı değişken adları, kodun okunmasını, anlaşılmasını ve bakımını kolaylaştırır. Kötü isimlendirme, geliştiricilerin kafasını karıştırabilir ve hata oluşma riskini artırabilir.
3. Derinlemesine iç içe geçmiş döngülerden veya koşul ifadelerinden kaçının
Döngülerde veya koşul ifadelerinde derin iç içe geçmeyi önlemek için kodu yeniden düzenleyin. Mantığı basitleştirmek için erken dönüşler veya yardımcı işlevler kullanın.
❌ Uygun değil:
eğer (kullanıcı) {
eğer (kullanıcı.isActive) {
eğer (kullanıcı.yetkisiVar) {
// Eylemi gerçekleştir
}
}
}✅ Uygunluk:
eğer (!kullanıcı) dön;
eğer (!kullanıcı.aktif) dön;
eğer (!kullanıcı.yetkisiVarmı) dön;
// İşlemi gerçekleştir
processUserAction(user);Bunun önemi: Derinlemesine iç içe geçmiş mantık, takip edilmesi, bakımı ve test edilmesi zordur. Bu durum, özellikle olumsuz durumlar ve erken hatalar için birim testleri yazmayı zorlaştırır. Erken dönüşlerle kontrol akışını düzleştirmek, kodun anlaşılmasını kolaylaştırır, test kapsamını artırır ve gizli uç durum hatalarının ortaya çıkma olasılığını azaltır.
4. Kod tabanının tamamında tutarlı bir hata işleme süreci sağlamak
Her zaman tutarlı bir hata işleme yaklaşımı uygulayın. İstisnaları tek tip bir şekilde işlemek için merkezi hata işlevlerini veya standartlaştırılmış kalıpları kullanın.
❌ Uygun değil:
try {
// Some code
} catch (e) {
console.error(e);
}✅ Uygunluk:
try {
// Some code
} catch (error) {
logError(error);
throw new CustomError('An error occurred', { cause: error });
}Bunun önemi: Tutarlı hata işleme, hata ayıklamayı kolaylaştırır, beklenmedik davranışları önler ve uygulama genelinde güvenilirliği sağlar.
5. Yapılandırma değerlerini sabit kodlamaktan kaçının
URL’ler, bağlantı noktaları veya gizli bilgiler gibi ortama özgü değerleri kodun içine sabit olarak yazmayın. Her zaman yapılandırma dosyalarını veya ortam değişkenlerini kullanın.
❌ Uygun değil:
const apiUrl = 'https://api.example.com';✅ Uygunluk:
const apiUrl = process.env.API_URL;Bunun önemi: Sabit kodlanmış değerler esnekliği azaltır, kodun güvenliğini düşürür ve farklı ortamlarda dağıtımı zorlaştırır. Yapılandırmaların kullanılması, bakım kolaylığı ve güvenliği sağlar.
6. İşlevlerin tek bir sorumluluğa odaklanmasını sağlayın
Her fonksiyonun tek ve net bir görevi yerine getirdiğinden emin olun. Birden fazla görevi üstlenen fonksiyonlardan kaçının; zira bu durum kafa karışıklığına ve bakımda zorluklara yol açabilir.
❌ Uygun değil:
function processUserData(user) {
const validatedUser = validateUser(user);
saveUserToDatabase(validatedUser);
sendWelcomeEmail(validatedUser);
}✅ Uygunluk:
işlev validateUser(kullanıcı) {
// doğrulama mantığı
}
işlev saveUserToDatabase(kullanıcı) {
// kaydetme mantığı
}
fonksiyon sendWelcomeEmail(kullanıcı) {
// e-posta gönderme mantığı
}Bunun önemi: Tek bir sorumluluğu olan işlevlerin test edilmesi, hata ayıklanması ve bakımı daha kolaydır. Bu işlevler, kodun yeniden kullanımını teşvik eder ve okunabilirliği artırır.
7. Sabit değerlerden kaçının
Kodun anlaşılırlığını ve bakım kolaylığını artırmak için sabit sayıları adlandırılmış sabitlerle değiştirin.
❌ Uygun değil:
const alan = uzunluk * 3,14159 * yarıçap * yarıçap;✅ Uygunluk:
const PI = 3,14159;
const alan = uzunluk * PI * yarıçap * yarıçap;Bunun önemi: Sihirli sayılar kodun anlamını belirsizleştirebilir ve gelecekteki değişiklikleri hataya açık hale getirebilir. Adlandırılmış sabitler bağlam sağlar ve hata oluşma riskini azaltır.
8. Küresel değişkenlerin kullanımını en aza indirin
Kod tabanındaki bağımlılıkları ve olası çakışmaları azaltmak için küresel değişkenlerin kullanımını sınırlayın.
❌ Uygun değil:
let user = { name: 'Alice' };
function greetUser() {
console.log(`Hello, ${user.name}`);
}✅ Uygunluk:
function greetUser(user) {
console.log(`Hello, ${user.name}`);
}
const user = { name: 'Alice' };
greetUser(user);Bunun önemi: Küresel değişkenler, gizli bağımlılıklar ve öngörülemeyen yan etkiler yaratabilir. Verilerin nereden geldiğini veya kod tabanında nasıl değiştiğini izlemeyi zorlaştırırlar. Verileri işlev parametreleri aracılığıyla açık bir şekilde aktarmak, veri akışını net ve kontrollü tutar; bu da modülerliği, hata ayıklamayı ve uzun vadeli bakım kolaylığını artırır.
9. Dize birleştirme için şablon sabitlerini kullanın
Daha iyi okunabilirlik ve performans için dize birleştirme yerine şablon sabitlerini tercih edin.
❌ Uygun değil:
const message = 'Merhaba, ' + user.name + '! ' + user.notifications + ' yeni bildirimin var.';✅ Uygunluk:
const message = `Hello, ${user.name}! You have ${user.notifications} new notifications.`;Bunun önemi: Şablon sabitleri, özellikle karmaşık dizeler veya çok satırlı içeriklerle çalışırken daha temiz bir sözdizimi sağlar ve okunabilirliği artırır.
10. Uygun giriş doğrulama işlemleri uygulayın
Geçersiz verilerin sisteme girmesini önlemek ve güvenliği artırmak için kullanıcı girdilerini her zaman doğrulayın.
❌ Uygun değil:
işlev processUserInput(giriş) {
// işleme mantığı
}✅ Uygunluk:
function validateInput(input) {
if (typeof input !== 'string' || input.trim() === '') {
throw new Error('Invalid input');
}
}
function processUserInput(input) {
validateInput(input);
// processing logic
}Bunun önemi: Giriş doğrulaması, hataları önlemek, veri bütünlüğünü sağlamak ve enjeksiyon saldırıları gibi güvenlik açıklarına karşı koruma sağlamak açısından hayati önem taşır.
11. Her çekme isteğinde tek bir mantıksal değişiklik tutun
Her çekme isteğinin (PR) tek bir mantıksal değişiklik veya özelliği içermesini sağlayın; birbiriyle ilgisiz düzeltmeleri, yeniden yapılandırmaları ve yeni özellik eklemelerini tek bir PR’da bir araya getirmekten kaçının.
❌ Uygun değil:
# "Fix login + update homepage"
--- auth.js
+ if (!user) throw new Error('User not found');
--- HomePage.js
- <button>Start</button>
+ <button>Begin Journey</button>✅ Uyumlu: (fark)
# PR 1: Fix login validation
+ if (!user) throw new Error('User not found');
# PR 2: Update homepage button
+ <button>Begin Journey</button>Bunun önemi: Küçük ve odaklanmış PR'ler kod incelemesini basitleştirir, istenmeyen yan etkilerin riskini azaltır ve birleştirme döngülerini hızlandırır. AI araçları, aynı PR içinde alakasız dosyaların, modüllerin veya etki alanlarının ne zaman değiştiğini tespit edebilir — bu, linter'ların belirleyemediği bir durumdur.
12. API’ler ve hizmetler için alan adıyla uyumlu adlandırma kullanın
API’leri, hizmetleri ve modülleri iş alanına göre adlandırın (örneğin, challengeService.createSubmission yerine handler1.doIt); adlar, varlığı ve eylemi açıkça yansıtmalıdır.
❌ Uygun değil:
// backend/services/handler.js
export async function doIt(data) {
return await process(data);
}
// routes/index.js
router.post('/submit', handler.doIt);✅ Uygunluk:
// backend/services/challengeService.js
export async function createSubmission({ userId, challengeId, answer }) {
return await challengeModel.create({ userId, challengeId, answer });
}
// routes/challenges.js
router.post('/submissions', challengeService.createSubmission);Bunun önemi: Etki alanı ile uyumlu adlandırma, kodun kendi kendini açıklamasını sağlar, yeni katkıcılar için netlik sağlar ve iş mantığıyla uyumludur. Yalnızca anlamsal bağlamın (varlık adları, hizmet katmanları) farkında olan bir yapay zeka, modüller arasında uyumsuz veya genel adlandırmaları tespit edebilir.
13. Testlerin hataları ve sınır durumlarını kapsadığından emin olun
Testleri yalnızca “normal akış” için değil, aynı zamanda hata durumları, uç durumlar ve sınır değerleri için de yazın; her bir kritik modülün hem olumlu hem de olumsuz testlere sahip olduğunu doğrulayın.
❌ Uygun değil:
describe('login', () => {
it('should succeed with correct credentials', async () => { … });
});✅ Uygunluk:
describe('login', () => {
it('should succeed with correct credentials', async () => { … });
it('should fail with incorrect password', async () => { … });
it('should lock account after 5 failed attempts', async () => { … });
});Bunun önemi: Geçersiz girdiler, zaman aşımları veya başarısız oturum açma girişimleri gibi sınır durumları gözden kaçtığında, iş açısından kritik mantık sıklıkla bozulur. Hem başarı hem de başarısızlık senaryolarını test etmek, uygulamanın gerçek dünya koşullarında güvenilir bir şekilde çalışmasını sağlar ve daha sonra tespit edilmesi zor olan gerilemeleri önler.
14. Katmanların birbirine karışmasını önleyin: Kullanıcı arayüzü bileşenleri iş mantığını yürütmemelidir
UI bileşenlerini (React, ön uç) iş mantığından ve veritabanı/hizmet çağrılarından uzak tutun; bu görevleri özel hizmetlere veya hook’lara devredin.
❌ Uygun değil:
// FreeCodeCamp-style
function CurriculumCard({ user, challenge }) {
if (!user.completed.includes(challenge.id)) {
saveCompletion(user.id, challenge.id);
}
return <Card>{challenge.title}</Card>;
}✅ Uygunluk:
function CurriculumCard({ user, challenge }) {
return <Card>{challenge.title}</Card>;
}
// In service:
async function markChallengeComplete(userId, challengeId) {
await completionService.create({ userId, challengeId });
}Bunun önemi: İş mantığını kullanıcı arayüzü bileşenlerine karıştırmak, katmanlar arasındaki sınırları bulanıklaştırır ve gelecekteki değişiklikleri riskli hale getirir. Ayrıca, ön uç geliştiricilerini arka uç mantığını anlamaya zorlar ve işbirliğini yavaşlatır. Sorumlulukları ayrı tutmak, her katmanın bağımsız olarak gelişmesini sağlar ve yeniden yapılandırma sırasında fark edilmeyen hataların ortaya çıkma riskini azaltır.
Sonuç
FreeCodeCamp’in kod deposunu inceleyerek, bu geniş kod tabanının düzenli, okunabilir ve bakımı kolay kalmasına yardımcı olan pratik kod inceleme kuralları belirledik. Bu 20 kural, herhangi bir otomatik araç tarafından zorunlu kılınmasa da, yıllar süren katkılardan elde edilen gerçek uygulamaları yansıtmaktadır.
Bu dersleri kendi projelerinizde uygulamak, netliği artırabilir, hataları azaltabilir ve işbirliğini daha sorunsuz hale getirebilir. Bu dersler, kodunuzu güvenli bir şekilde ölçeklendirmek için sağlam bir temel oluşturur ve projenin büyümesi durumunda kodun güvenilirliğini ve üzerinde çalışmanın kolaylığını korur.
Kod incelemesi, sadece sözdizimini kontrol etmekten ibaret değildir. Zaman içinde kodunuzun kalitesini ve bütünlüğünü korumakla ilgilidir. FreeCodeCamp gibi olgun bir açık kaynak projesinden dersler çıkarmak, geliştiricilere herhangi bir kod tabanını iyileştirmeleri için somut bir rehberlik sağlar.

