В английской версии недавно выпущенного анализатора Cache-Control отображался японский текст: вместо «Fresh» статус был «新鮮». Ошибка была вызвана общей логикой, которая возвращала жестко закодированные японские строки, в то время как сама страница предоставляла только английские метки.
Разработчик создает серию легковесных браузерных инструментов, каждый из которых имеет английскую и японскую версии страниц, использующие одни и те же функции парсинга и основную логику. Должны различаться только видимые формулировки. Когда анализатор Cache-Control был выпущен, английский интерфейс отображал правильные метки, но значения, которые он выводил, поступали из уровня логики, где все еще содержались японские литералы. Ошибок в консоли не было; страница выглядела нормально, однако информация, представленная англоязычным пользователям, была неверной.
Почему общая логика может подвести при переводе
Баг стал следствием архитектурного решения: основная функция, определяющая, что именно нужно показать, возвращала строковые литералы на японском языке. Уровень страницы, отвечающий за окружающий английский текст, так и не получил возможности заменить эти значения. Поскольку логика и UI были четко разделены, проблема оставалась незаметной во время тестирования — технически всё «работало», хотя язык, отображаемый пользователю, был неверным.
Недостаток заключается в том, что язык, используемый внутри общего модуля, становится языком по умолчанию для любого фронтенда, который его использует. Если требуется другой язык, этот «дефолт» превращается в скрытый баг.
Исправление: ключи, пакеты и страховочная сетка
Автор переписал архитектуру, чтобы разделить зоны ответственности:
- Пакеты сообщений теперь содержат все читаемые человеком строки для каждого языка.
- Общая логика возвращает только символьные ключи, а не сырой текст.
- Страницы ищут подходящее слово в соответствующем пакете на основе ключа.
Если сообщение должно включать число, новый код использует небольшую функцию вместо шаблонной строки. Это позволяет каждому языку самостоятельно определять место для числа, учитывая различия в порядке слов.
Также был добавлен простой этап статического анализа: процесс сборки сканирует общие файлы на наличие японских символов. Если они обнаруживаются, разработчик немедленно получает уведомление, что предотвращает повторное появление жестко закодированного иностранного текста.
Чему этот опыт научил автора
- Перевод служит этапом проверки. При написании английских сообщений автор заметил, что некоторые японские эквиваленты были расплывчатыми. Перевод заставил использовать более четкие формулировки на обоих языках.
- Общие функции, возвращающие строки, фиксируют язык для всех. Если функция сама определяет язык, любой потребитель, ожидающий другой язык, наследует эту ошибку. Баг — это не сбой UI, а ошибка в логике.
Рекомендации для тех, кто поддерживает многоязычные инструменты
- Возвращайте ключи, а не строки, из основных функций. Позвольте уровню UI заниматься локализацией.
- Или передавайте нужные строки в функцию в качестве параметров. Это сделает логику независимой от языка.
- Проверяйте общие модули на наличие жестко закодированного текста на родном языке. Быстрый поиск не-ASCII символов поможет выявить скрытые проблемы.
- Добавьте проверку наличия иностранных символов в общем коде на этапе сборки. Раннее обнаружение лучше, чем путаница после релиза.
На что обратить внимание в будущем
Вывод: Если в вашем проекте код разделяется между языковыми версиями, убедитесь, что общая часть никогда не определяет формулировки. Пусть каждая страница предоставляет свои собственные слова, и тогда вы избежите неловкости, когда английская страница внезапно начинает говорить по-японски.
