İçindekiler
Eksik çeviriler, pipeline'ınızın her aşamasından sıyrılan türden bir hatadır. Birim testleri geçer çünkü çeviri dosyalarını kontrol etmez. Entegrasyon testleri geçer çünkü varsayılan dilde çalışır. QA geçer çünkü manuel testler nadiren on iki dilin tamamını kapsar. Sonra Brezilya'daki bir kullanıcı, bir buton etiketi görünmesi gereken yerde checkout.confirm_button yazar ve ekibinizi dikkatsiz gösteren bir hata raporu gelir.
Sorun, ekiplerin çevirileri unutması değildir. Sorun, bir tür denetleyicisinin tür hatalarını ya da bir linter'ın kod stili sorunlarını yakaladığı gibi çeviri boşluklarını otomatik olarak yakalayan bir mekanizmanın olmamasıdır. Kodunuzda ESLint, Prettier, TypeScript ve tam bir CI pipeline'ı var. Çevirilerinizde ise... umarız birinin güncellemeyi hatırladığı bir JSON dosyası var.
Bu yazıda, eksik çevirileri, yer tutucu uyumsuzluklarını, sahipsiz anahtarları ve sabit kodlanmış dizeleri production'a ulaşmadan yakalayan otomatik i18n sağlık kontrollerinin nasıl uygulanacağı ele alınmaktadır.
i18n Sağlık Kontrolü Aslında Neyi Kontrol Eder?
Kapsamlı bir i18n sağlık kontrolü, çeviri kurulumunuzun dört boyutunu değerlendirir:
1. Kapsam: Tüm Anahtarlar Çevrildi mi?
Kapsam, en doğrudan ve en etkili kontroldür. Kaynak kodunuzda kullanılan her çeviri anahtarı için, her hedef dilde bir çeviri mevcut mu?
Kaynak kod referansları: 1.247 anahtar İngilizce (kaynak): 1.247/1.247 (%100) İspanyolca: 1.235/1.247 (%99) Fransızca: 1.198/1.247 (%96) Japonca: 1.150/1.247 (%92) Korece: 1.089/1.247 (%87)
Kapsam kontrolü en yaygın senaryoyu yakalar: bir geliştirici yeni bir özellik ekler, İngilizce dizeleri yazar ve bir sonraki göreve geçer. Anahtarlar İngilizce JSON dosyasına girer ama çeviri için hiç gönderilmez. Kapsam kontrolü olmadan boşluk, bir kullanıcı bununla karşılaşana kadar görünmez kalır.
Kapsam kontrolleri ayrıca namespace uyumsuzluklarını da yakalar. Kodunuz t('checkout.confirm') referansı veriyorsa ama Korece için checkout namespace'i mevcut değilse, bu Korece kullanıcılara ham anahtar gösterecek bir kapsam boşluğudur.
2. Kalite: Çeviriler Yapısal Olarak Doğru mu?
Kapsam, bir çevirinin var olup olmadığını söyler. Kalite ise çalışma zamanında doğru çalışıp çalışmayacağını söyler.
En kritik kalite kontrolü yer tutucu doğrulamasıdır. İngilizce dizeniz şuysa:
"You have {count} items in your cart, {name}."
O zaman bu dizenin her çevirisi tam olarak {count} ve {name} içermelidir. {count} yerine {nombre} yazan bir Fransız çevirmen çalışma zamanı hatası yaratır — interpolasyon motoru {nombre} için bir değer bulamaz ve ya ham yer tutucuyu görüntüler ya da hata fırlatır.
Diğer kalite kontrolleri şunları içerir:
- Boş değerler: Bir dil dosyasında mevcut olan ancak boş dize içeren anahtarlar. Bunlar genellikle gerçek çeviri yapılmadan programatik anahtar oluşturmaya işaret eder.
- Kaynakla özdeş dizeler: Kaynak dille karakter karakter aynı olan çeviriler. Bazı dizeler (marka adları, URL'ler) meşru olarak aynıdır, ancak yüksek sayı genellikle çevrilmemiş içeriğe işaret eder.
- Aşırı uzunluk: Kaynak koddan önemli ölçüde daha uzun olan çeviriler; bunlar UI konteynerlerini taşırabilir. Almanca çeviriler İngilizce'den %30-40 daha uzun olmasıyla bilinir.
3. Yapı: Çeviri Dosyaları Temiz mi?
Yapı kontrolleri, çeviri dosyalarınızın organizasyonunu ve düzenini değerlendirir:
- Sahipsiz anahtarlar: Çeviri dosyalarında mevcut olan ancak kaynak kodda hiç referans verilmeyen anahtarlar. Özellikler kaldırıldığında ama çeviri dosyaları temizlenmediğinde birikir. Çevirmen çabasını boşa harcar ve kafa karışıklığı yaratır.
- Yinelenen anahtarlar: Tek bir dosyada iki kez tanımlanan aynı anahtar. JSON, yinelenen anahtarlarda hata vermez — sessizce sonuncusunu kullanır ve bu da kafa karıştırıcı davranışlara yol açabilir.
- Adlandırma tutarsızlığı: Anahtarlarınızın %90'ı
snake_casekullanırken birkaçıcamelCasekullanıyorsa, bu tutarsızlık anahtarları bulmayı ve bakımını yapmayı zorlaştırır.
4. Kod: Dizeler Düzgün Biçimde Uluslararasılaştırıldı mı?
Kod analizi, çeviri fonksiyonlarına sarılması gereken kaynak dosyalarınızdaki sabit kodlanmış dizeleri bulmak için AST ayrıştırması kullanır.
// İşaretlendi: sabit kodlanmış kullanıcıya yönelik dize
<h1>Welcome to our app</h1>
// İşaretlenmedi: düzgün uluslararasılaştırılmış
<h1>{t('home.welcome_title')}</h1>
// İşaretlenmedi: kullanıcıya yönelik olmayan (CSS sınıfı, data niteliği)
<div className="container" data-testid="home">
Bu kontrol, i18n borcunu kaynağında yakalar. i18n kurulumunuza aşina olmayan yeni geliştiriciler sabit kodlanmış dizeler yazar. Otomatik kontrol olmadan, bu dizeler biri çeviri denetimi sırasında fark edene kadar kalıcı olur.
Sağlık Skoru: Karmaşıklığı Bir Sayıya İndirgemek
Bireysel kontroller ayrıntılı raporlar üretir, ancak CI entegrasyonu ve trend takibi için tek bir sayıya ihtiyaç duyarsınız: sağlık skoru.
İyi tasarlanmış bir sağlık skoru, kategorileri kullanıcı etkisine göre ağırlıklandırır:
| Kategori | Ağırlık | Gerekçe |
|---|---|---|
| Kapsam | %40 | Eksik çeviriler kullanıcıları doğrudan etkiler |
| Kalite | %30 | Yer tutucu hataları çalışma zamanı hatalarına neden olur |
| Yapı | %20 | Sahipsiz anahtarlar çabayı boşa harcar ama UX'i bozmaz |
| Kod | %10 | Sabit kodlanmış dizeler borçtur, anında kopukluk değil |
87/100 puan alan bir proje şöyle dağılabilir:
Genel: 87/100 GEÇTİ Kapsam 92/100 ████████████████████ 3 eksik anahtar Kalite 85/100 █████████████████░░░ 2 yer tutucu uyumsuzluğu Yapı 78/100 ███████████████░░░░░ 12 sahipsiz anahtar Kod 90/100 ██████████████████░░ 4 sabit kodlanmış dize
Geçme/kalma eşiği yapılandırılabilir. 80 eşiği çoğu ekip için pratiktir — gerçek sorunları yakalamaya yetecek kadar katı, küçük uyarıların dağıtımları engellemeyeceği kadar esnek.
CI/CD'de i18n Sağlık Kontrolleri Kurma
Sağlık kontrollerinin asıl değeri, her pull request'te otomatik olarak çalıştırılmalarından gelir. GitHub Actions workflow'u nasıl kurulur:
# .github/workflows/i18n-doctor.yml
name: i18n Health Check
on:
pull_request:
paths:
- "locales/**"
- "src/**"
- "messages/**"
jobs:
doctor:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
- name: Install dependencies
run: bun install
- name: Run i18n Doctor
run: bunx @better-i18n/cli doctor --ci --threshold 80
env:
BETTER_I18N_API_KEY: ${{ secrets.BETTER_I18N_API_KEY }}
--ci Flag'i Ne Yapar?
--ci flag'i, Doctor'ın CI ortamları için davranışını değiştirir:
- Çıkış kodu: Tarama başarısız olursa çıkış kodu 1 döndürür, böylece GitHub Actions işi başarısız olur
- GitHub annotation'ları: Sorunları GitHub Actions annotation formatında çıktılar, böylece PR diff'inde satır içi yorumlar olarak görünürler
- Özet: GitHub Actions kontrol çıktısı için yapılandırılmış bir özet üretir
- Etkileşimsiz: İlerleme çubuklarını ve renkli çıktıyı bastırır
Path Filter'lar Önemlidir
Workflow yapılandırmasındaki paths filtresi performans açısından önemlidir. Olmadan, sağlık kontrolü, yalnızca belgeleri veya çeviri etkisi olmayan backend kodunu değiştiren PR'lar dahil her PR'da çalışır. Çeviri dosyası dizinlerinize ve kaynak kod dizinlerinize filtreleyin.
Platforma Sonuç Raporlama
Sonuçları çeviri yönetim platformunuza göndermek için --report flag'ini ekleyin:
- name: Run i18n Doctor
run: bunx @better-i18n/cli doctor --ci --report --threshold 80
env:
BETTER_I18N_API_KEY: ${{ secrets.BETTER_I18N_API_KEY }}
Raporlar commit SHA'sını, branch adını, dosya sayısını ve anahtar sayısını içerir. Zamanla bu, iyileştirmeleri takip etmek, gerilmeleri yakalamak ve ekip hedefleri belirlemek için kullanabileceğiniz i18n sağlık geçmişi oluşturur.
Otomatik Oluşturulan Workflow'lar
GitHub Actions'ı manuel olarak yapılandırmak gereksiz sürtüşme gibi görünüyorsa, bazı çeviri platformları (Better i18n dahil) workflow dosyasını sizin için oluşturabilir. Platform, önceden yapılandırılmış bir workflow dosyasıyla deponuzda bir PR açmak için GitHub API'sini kullanır. Siz inceler, birleştirirsiniz ve sağlık kontrolü etkin olur.
Kontrol Başarısız Olduğunda Ne Olur?
Başarısız bir sağlık kontrolü, yalnızca kırmızı bir X değil, eyleme dönüştürülebilir bilgiler sağlamalıdır. Yararlı bir başarısızlık şöyle görünür:
Eksik Çeviri Anahtarları
Hata: 12 anahtar hedef dillerde eksik
checkout.confirm_order
Eksik: fr, de, ja, ko
Commit'te eklendi: abc1234 (2 gün önce)
Dosya: src/pages/Checkout.tsx:45
checkout.payment_method
Eksik: fr, de, ja, ko
Commit'te eklendi: abc1234 (2 gün önce)
Dosya: src/pages/Checkout.tsx:52
Geliştirici tam olarak hangi anahtarların, hangi dillerde eksik olduğunu, ne zaman eklendiğini ve nerede kullanıldığını görür. Çözüm nettir: birleştirmeden önce bu anahtarlar için çeviri talep edin.
Yer Tutucu Uyumsuzlukları
Hata: notifications.new_messages (de) içinde yer tutucu uyumsuzluğu
Kaynak: "You have {count} new messages from {sender}"
Hedef: "Sie haben {anzahl} neue Nachrichten von {sender}"
Eksik: {count}
Fazladan: {anzahl}
Geliştirici veya çevirmen tam uyumsuzluğu görür ve Almanca çeviriyi {anzahl} yerine {count} kullanacak şekilde düzeltebilir.
Sabit Kodlanmış Dizeler
Uyarı: JSX'te sabit kodlanmış dize (src/components/Header.tsx:23)
<h1>Welcome back!</h1>
Öneri: <h1>{t('header.welcome_back')}</h1>
Bu bir uyarıdır, hata değil — varsayılan olarak PR'ı engellemez. Ancak raporda görünür ve kod analizi skoruna katkıda bulunur.
Gerçek Dünya Etkisi: Önce ve Sonra
Önce: Manuel Süreç
- Geliştirici 30 yeni anahtarla yeni özellik ekler
- Geliştirici İngilizce çevirileri ekler
- Geliştirici PR açar, incelenir ve birleştirilir
- İki hafta sonra QA, özelliği Fransızca test eder — 30 ham anahtar bulur
- QA bir hata raporu açar
- Geliştirici çeviriler için bir bilet oluşturur
- Çevirmen Fransızca çevirileri sağlar
- Geliştirici çeviri dosyasını commit eder, yeni PR açar
- Almanca, Japonca, Korece vb. için tekrar edin
Kod birleşiminden tamamen çevrilmiş özelliğe geçen süre: 3-6 hafta.
Sonra: Otomatik Sağlık Kontrolleri
- Geliştirici 30 yeni anahtarla yeni özellik ekler
- Geliştirici İngilizce çevirileri ekler
- Geliştirici PR açar
- CI, i18n Doctor'ı çalıştırır — "fr, de, ja, ko'da 30 anahtar eksik" ile başarısız olur
- Geliştirici platform üzerinden çeviri talep eder
- Çeviriler gelir (AI tarafından dakikalar içinde oluşturulur, insan tarafından saatler içinde incelenir)
- Geliştirici çevirileri PR'a ekler
- CI yeniden çalışır — geçer
- PR tüm diller tamamlanmış olarak birleştirilir
Kod birleşiminden tamamen çevrilmiş özelliğe geçen süre: Aynı gün.
Fark sadece hız değil — sorunu doğru yerde yakalamakla ilgili. CI kontrolü, anahtarların eklendiği aynı PR'da eksik çevirileri yakalar; geliştirici henüz özellik hakkında tam bağlama sahipken. Üç hafta sonra gelen bir hata raporu, geliştiricinin zaten geçtiği bir özelliğe geri dönerek bağlamı yeniden kurmasını gerektirir.
Zaman İçinde Sağlığı Takip Etmek
Tek bir sağlık skoru, geçme/kalma kapısı için kullanışlıdır. Sağlık skorlarının geçmişi ise trendleri anlamak için kullanışlıdır.
Doctor raporlarını bir platform panosuna gönderdiğinizde şunları takip edebilirsiniz:
- Skor yörüngesi: i18n sağlığınız iyileşiyor mu, stabil mi yoksa kötüleşiyor mu?
- Kategori trendleri: Belki kapsamınız mükemmel ama sahipsiz anahtarlar birikiyor. Kategori dağılımı, temizleme çabalarını nereye yoğunlaştıracağınızı gösterir.
- Branch başına karşılaştırma: Özellik branch'leri genellikle daha düşük skorlara sahiptir (çevirisi olmayan yeni anahtarlar). Ana branch'in tutarlı şekilde yüksek skor koruması gerekir.
- Projeler arası karşılaştırma: Birden fazla ürüne sahip organizasyonlar için, hangilerinin ilgi gerektirdiğini belirlemek amacıyla i18n sağlığını projeler arasında karşılaştırın.
Ekip Hedefleri Belirleme
Sağlık skorları ölçülebilir i18n hedefleri belirlemeyi mümkün kılar:
- "Ana branch'te 90+ sağlık skoru koru" — bir kalite standardı
- "Çeyreğin sonuna kadar sahipsiz anahtarları 200'den 50'ye indir" — bir temizleme girişimi
- "Sıfır yer tutucu uyumsuzluğu" — en kritik kontrol için sıfır hata hedefi
Yaygın İtirazlar ve Yanıtlar
"Sadece iki dilimiz var, buna ihtiyacımız yok." İki dil, kapsam boşluklarının ve yer tutucu uyumsuzluklarının kullanıcıya görünür hatalara neden olması için yeterlidir. Sağlık kontrolü hafiftir — CI pipeline'ınıza dakikalar değil, saniyeler ekler.
"Çevirmenlerimiz kaliteyi halleder." Çevirmenler dilsel kaliteyi sağlar. Sağlık kontrolleri teknik kaliteyi sağlar — yer tutucu doğruluğu, anahtar kapsamı, dosya yapısı. Bunlar farklı konulardır. Bir çevirmen, bir anahtarın kaynak kodunuzda referans alınıp alınmadığını bilemez.
"Daha fazla dilimiz olduğunda bunu ekleriz." i18n borcu birikerek büyür. İki dille biriktirdiğiniz sahipsiz anahtarlar, sabit kodlanmış dizeler ve tutarsız adlandırma, üçüncü, dördüncü ve beşinci dili eklediğinizde çok daha zor düzeltilir hale gelir. Sağlık kontrollerine erken başlamak, sonradan uyarlamaktan daha ucuzdur.
"CI'ımız zaten yavaş."
8 dilli 10.000 anahtarlık bir projenin Doctor taraması 10 saniyenin altında sürer. AST analizini düşürmek ve bunu 3 saniyenin altına indirmek için --skip-code kullanın. GitHub Actions yapılandırmasındaki path filtresi, kontrolün yalnızca çeviriyle ilgili dosyalara dokunan PR'larda çalışmasını sağlar.
Başlarken
Better i18n kullanıyorsanız, Doctor komutu CLI'ya yerleşik olarak gelir:
# CLI'yı yükle bun add -g @better-i18n/cli # İlk sağlık kontrolünüzü çalıştırın bi18n doctor # CI modunda raporlamayla çalıştırın bi18n doctor --ci --report --threshold 80
Better i18n kullanmıyorsanız, bu yazıdaki prensipler herhangi bir çeviri kurulumuna uygulanabilir. Benzer kontrolleri özel script'lerle oluşturabilirsiniz:
- Çeviri anahtar referansları için kaynak kodunuzu ayrıştırın
- Referans verilen anahtarları çeviri dosyalarınızla karşılaştırın
- Yer tutucu tutarlılığını doğrulayın
- Sonuçları CI sisteminizin annotation formatında çıktılayın
Önemli olan hangi aracı kullandığınız değil. Önemli olan, eksik çevirilerin kullanıcılar tarafından bulunan bir sürpriz olmaktan çıkıp geliştiriciler tarafından bulunan bir CI kontrolüne dönüşmesidir.
Eksik çeviriler önlenebilir hatalardır. Onları CI'da yakalamaya başlayın — Better i18n Doctor'ı kurun ve bugün ilk sağlık kontrolünüzü çalıştırın.