Zadaj pytanie i otrzymaj streszczenie dokumentu, odwołując się do tej strony i wybranego dostawcy AI
Treść tej strony została przetłumaczona przy użyciu sztucznej inteligencji.
Zobacz ostatnią wersję oryginalnej treści w języku angielskimJeśli masz pomysł na ulepszenie tej dokumentacji, zachęcamy do przesłania pull requesta na GitHubie.
Link do dokumentacji na GitHubieKopiuj dokument Markdown do schowka
Jak wykrywać brakujące tłumaczenia, zanim zrobią to użytkownicy
Brakujące tłumaczenie prawie nigdy nie rzuca wyjątku. W zależności od konfiguracji wyświetla japońskiemu użytkownikowi tekst po angielsku lub drukuje checkout.summary.total wprost na stronie produkcyjnej. Obydwa przypadki trafiają na produkcję, przechodzą code review i zostają zauważone przez klienta, a nie przez Ciebie.
Spis treści
Dotyczy to każdej biblioteki, której używasz
Nic z tego, co tu opisano, nie jest ograniczone do jednego konkretnego stosu technologicznego. Poniższe warstwy detekcji działają identycznie w i18next, react-i18next, next-intl, react-intl, vue-i18n, next-translate czy Lingui, ponieważ wszystkie rozwiązują klucze w ten sam sposób i zawodzą według tego samego schematu.
Narzędzia również są przenośne. Jeśli Twoje teksty znajdują się w katalogach JSON, wtyczka Sync JSON podłącza Intlayer do tych plików, dając Ci dostęp do poleceń audytu, wypełniania i testowania bez przenoszenia treści i bez zmiany choćby jednego importu:
Skopiuj kod do schowka
Jeśli zależy Ci również na zachowaniu dotychczasowego runtime API, adaptery kompatybilności tworzą aliasy dla useTranslation, $t i pokrewnych na poziomie bundlera. W każdym przypadku traktuj poniższe komendy jako praktyczną realizację koncepcji, a nie sztywny wymóg.
Dlaczego braki są niewidoczne
Każda biblioteka i18n rozwiązuje klucz według tego samego łańcucha: sprawdź aktywny język, sięgnij po język domyślny (fallback), a jeśli to zawiedzie, zwróć sam klucz. To właśnie ten ostatni krok stanowi sedno problemu. Nie ma błędu, nie ma ostrzeżenia na produkcji i żaden test nie zgłasza awarii, ponieważ żaden element potoku nie traktuje brakującego klucza jako anomalii.
Fallback tylko pogarsza sprawę zamiast ją naprawiać. Strona renderująca się po cichu w języku angielskim wygląda całkowicie poprawnie dla anglojęzycznego programisty i dla każdego zautomatyzowanego testu. Błąd jest widoczny wyłącznie dla osoby, która nie rozumie wyświetlonego tekstu.
Pytanie nie brzmi zatem "jak obsługiwać brakujące tłumaczenia w runtime". Brzmi ono: "jak uniemożliwić zmergowanie brakującego tłumaczenia".
Cztery warstwy, w których możesz je wychwycić
Każda warstwa wyłapuje to, czego inne nie potrafią dostrzec. Najlepiej wdrożyć więcej niż jedną.
Otwórz tabelę w oknie modalnym, aby wyraźnie zobaczyć całą zawartość
| Warstwa | Co wykrywa | Co pomija |
|---|---|---|
| Typy | Klucze, które w ogóle nie istnieją | Klucz istnieje, ale nie ma wartości w ja |
| Linter | Teksty na sztywno, niewysłane do tłumaczenia | Klucze brakujące w konkretnym katalogu |
| Audyt | Pokrycie językowe każdego zadeklarowanego klucza | Teksty, które nigdy nie zostały oznaczone do tłumaczenia |
| Testy renderowania | Klucze, które się rozwiązują, ale źle renderują | Wszystko, co nie zostało objęte testem |
Najczęstszą luką w zespołach jest trzeci wiersz: programiści wiedzą, że ich klucze są poprawne pod kątem typów, ale nic nie sprawdza, czy wszystkie osiemnaście języków rzeczywiście posiada przypisaną wartość.
Warstwa 1: uczyń klucz typem, a nie ciągiem znaków
t("checkout.summry.total") to literówka, która bez trudu się kompiluje. Jeśli Twoje klucze są zwykłymi ciągami znaków, każda zmiana nazwy niesie ryzyko na produkcji, a każde usunięcie pozostawia osierocone wpisy.
Typowane klucze zamieniają to w błąd kompilacji. react-i18next wspiera to przez declaration merging, next-intl wnioskuje typy ze struktury wiadomości, Lingui generuje identyfikatory z tekstu źródłowego, a Intlayer tworzy ścisłe typy z plików deklaracji. Każde z tych rozwiązań działa; różnią się jedynie ilością kodu konfiguracyjnego.
Ta warstwa jest niezbędna, lecz niewystarczająca. Typy opisują kształt Twojego katalogu domyślnego. Nie informują jednak, czy w języku koreańskim istnieje wartość dla danego klucza.
Warstwa 2: sprawdzaj linterem teksty, które nigdy nie stały się kluczami
Tłumaczenie, którego nie możesz znaleźć, to często to, które nigdy nie zostało wyodrębnione. Etykieta wpisana na sztywno w komponencie jest niewidoczna dla każdego audytu katalogów, ponieważ z perspektywy narzędzi po prostu nie istnieje.
Wtyczka ESLint dla Intlayer rozwiązuje ten problem regułą no-raw-text, uzupełnioną o no-unused-content dla sytuacji odwrotnej: treści zadeklarowanej, z której nic już nie korzysta.
Skopiuj kod do schowka
no-unused-content zapobiega niekontrolowanemu rozrastaniu się katalogów. Martwe klucze nie psują działania aplikacji, ale niepotrzebnie powiększają rachunki za tłumaczenia. Pełna lista reguł znajduje się w dokumentacji wtyczki ESLint.
Warstwa 3: audyt pokrycia języków
To warstwa, która bezpośrednio odpowiada na właściwe pytanie. Intlayer dostarcza ją jako polecenie CLI:
Skopiuj kod do schowka
Polecenie odczytuje skonfigurowane języki i zadeklarowane słowniki, po czym zgłasza, którym kluczom brakuje tłumaczeń, w jakich językach i w jakim pliku.
Ważny szczegół przed włączeniem tego do procesów CI: CLI drukuje raport, ale kończy działanie z kodem wyjścia 0. Jeśli dodasz je do potoku, oczekując przerwania buildu, otrzymasz zielony build z długim raportem tekstowym, którego nikt nie przeczyta. Do blokowania kompilacji użyj programistycznego API opisanego poniżej.
Warstwa 4: asercje w zestawie testów
listMissingTranslations() zwraca dokładnie ten sam audyt w formie ustrukturyzowanych danych, co idealnie nadaje się do stworzenia bramki kompilacji (build gate).
Skopiuj kod do schowka
Zwracane są trzy pola o istotnym znaczeniu:
missingTranslations: w rozbiciu na klucze, jakich języków brakuje i w jakim pliku. To właśnie te dane drukujesz w przypadku błędu testu.missingLocales: suma wszystkich brakujących języków we wszystkich kluczach.missingRequiredLocales: ograniczone dorequiredLocalesz Twojej konfiguracji (lub wszystkie języki, jeśli opcja nie została zdefiniowana).
requiredLocales sprawia, że bramka jest znośna w praktyce
Wydawanie aplikacji w osiemnastu językach nie oznacza, że wszystkie osiemnaście musi być w 100% gotowych, aby móc wdrożyć kod. Większość zespołów posiada poziom krytyczny, który blokuje wydanie, oraz poziom uzupełniany na bieżąco.
Skopiuj kod do schowka
Bez requiredLocales każdy zadeklarowany język jest bezwzględnie wymagany, a Twój build pozostanie czerwony, dopóki nie spłynie ostatnie tłumaczenie. W rezultacie zespoły najczęściej całkowicie wyłączają tę weryfikację, co jest gorsze niż brak jakichkolwiek testów.
Wykrywanie braków, które już trafiły na produkcję
Powyższe warstwy chronią przed nowymi lukami. W przypadku aplikacji, która już działa na produkcji, pomagają dwie techniki.
Pseudolokalizacja. Uruchom aplikację ze sztucznym językiem, w którym każdy ciąg znaków jest zmodyfikowany, na przykład [!!! Ĉĥéçķöũţ !!!]. Wszystko, co nadal wyświetla się po angielsku, jest zaszyte w kodzie na stałe. Pozwala to w dziesięć minut wykryć to, czego audyt katalogów strukturalnie nie jest w stanie zobaczyć, ponieważ testuje wyrenderowaną stronę, a nie same pliki z danymi.
Crawlowanie własnej witryny. Jeśli używasz zlokalizowanych adresów URL, pobierz próbkę podstron dla każdego języka i przeszukaj kod HTML pod kątem ciągów znaków z języka domyślnego. Strona w /ja/ zawierająca zwrot "Add to cart" to albo brakujące tłumaczenie, albo nieoczekiwany fallback.
Skopiuj kod do schowka
Uzupełnianie luk
Gdy wiesz już, czego brakuje, intlayer fill uzupełnia puste wpisy, a opcja autoFill potrafi generować pliki dla poszczególnych języków bezpośrednio podczas deklarowania zawartości. Zobacz autoFill.
Warto spojrzeć na to trzeźwym okiem: automatyczne uzupełnianie maszynowe zamienia lukę widoczną w lukę niewidoczną. Klucz ma teraz wartość, audyt świeci na zielono, ale nikt nie sprawdził sensu sformułowań. Używaj tego do odblokowania release'u, a następnie przekazuj teksty do weryfikacji człowiekowi w przypadku wszystkiego, co klient czyta przed podjęciem decyzji. To rusztowanie pomocnicze, a nie gotowy produkt.
Częste błędy
- Traktowanie mechanizmu fallback jako tarczy bezpieczeństwa. To strategia renderowania awaryjnego, a nie siatka ochronna. Cicho wyświetlana angielska strona to błąd, którego nikt nie zgłasza.
- Poleganie na raporcie CLI do blokowania CI.
intlayer content testkończy się kodem zero. Wymagaj asercji w teście. - Wymaganie absolutnie każdego języka. Kontrola zostaje usunięta przy pierwszym zablokowanym wydaniu.
- Audytowanie wyłącznie katalogów, a nigdy wyrenderowanego ekranu. Teksty zaszyte w kodzie są z definicji niewidoczne w katalogach.
- Testowanie tylko języka domyślnego. To jedyny język, którego na pewno nigdy nie zabraknie.
- Kończenie procesu na automatycznym wypełnieniu. Zielony audyt przy niezweryfikowanych tekstach.
Warto przeczytać
- Testowanie treści: audyt CLI, programistyczne API i asercje UI
- Reguły wtyczki ESLint, w tym
no-raw-textino-unused-content - autoFill: generowanie plików deklaracji dla poszczególnych języków
- Dokumentacja konfiguracji:
locales,requiredLocales,defaultLocale - Raporty benchmarkowe porównujące frameworki
- Adapter kompatybilności i18next
- Co w rzeczywistości obejmuje internacjonalizacja
- i18n na poziomie komponentów a podejście scentralizowane
Komentarze
Nie ma jeszcze komentarzy. Bądź pierwszą osobą, która podzieli się swoimi przemyśleniami.
