Создание многоязычных приложений с локальными библиотеками

Создание приложений, которые говорят на родном языке пользователя, больше не является роскошью - это бизнес-необходимость. Поскольку мобильное использование продолжает взрываться во всем мире, пользователи ожидают, что приложения будут чувствовать себя локальными, от текста, который они читают, до способа форматирования чисел и дат. React Native, кросс-платформенная структура, разработанная Meta, позволяет разработчикам создавать эффективные мобильные приложения для iOS и Android из одной кодовой базы. Добавление многоязычной поддержки таких приложений, однако, требует тщательного планирования и правильного инструментария. Это всеобъемлющее руководство проведет вас через основы локализации в React Native, вводит самые популярные библиотеки и предоставляет практические шаги для создания готового к производству многоязычного приложения.

Локализация против интернационализации: определение терминов

Перед погружением в код важно различать две связанные концепции. Интернационализация (i18n) — это процесс проектирования вашего приложения, чтобы оно могло быть адаптировано к различным языкам и регионам без необходимости инженерных изменений. Он включает в себя извлечение текста, использование локально-сознательного форматирования для дат и чисел и планирование для различных систем письма. Локализация (l10n) — это фактическая адаптация вашего приложения к определенному языку или региону — перевод строк, настройка макета для правых-левых сценариев и обработка локальных конвенций.

Сам React Native предоставляет только несколько базовых API для обнаружения локализации (например, из модуля ), но полная локализация требует выделенной библиотеки для управления ресурсами перевода, переключения языков и форматирования.

Основные библиотеки локализации для React Native

Три библиотеки доминируют в ландшафте локализации React Native. Понимание их ролей и того, как они дополняют друг друга, является первым шагом к надежной реализации.

React-i18next

Построенный поверх i18next, один из самых популярных фреймворков интернационализации для JavaScript, является полным решением для управления переводом. Он обеспечивает React-хуки (), Компоненты более высокого порядка и компонент перевода, который автоматически переоформляется при изменении языка. Библиотека поддерживает промежуточное воспроизведение имен (разделение переводов на отдельные файлы), интерполяцию, плюрализацию, контекстно-специфические переводы и сложное обнаружение языка.

Ключевые преимущества react-i18next включают в себя богатую экосистему плагинов и возможность загрузки переводов по требованию (разделение их по маршруту или функции). Он также легко работает с рендерингом на стороне сервера и может использоваться в нереагирующих частях вашего кода Android или iOS через базовый движок i18next.

реактивно-нативный-локализованный

В то время как react-i18next обрабатывает логику перевода, имеет дело с информацией о местоположении устройства. Он раскрывает текущую локацию пользователя, часовую зону, температурный блок, систему измерения и тип календаря. Эти значения имеют решающее значение для правильного форматирования чисел, дат и валют. Поскольку приложения React Native работают на двух разных платформах, доступ к этой информации изначально использовался для того, чтобы быть громоздким; обертывает нативные API и делает их доступными в качестве простого объекта JavaScript.

Вы можете объединить реактивно-нативную локализацию с реактивно-i18next, подав обнаруженный язык в инициализацию i18next. Это дает вам бесшовный, управляемый устройством опыт: когда пользователь меняет язык своего телефона, приложение автоматически переключается на соответствующий перевод.

i18n-js

Для небольших проектов или разработчиков, предпочитающих легкий подход, FLT:5 предлагает минималистичный API. Он обеспечивает простой поиск перевода, правила плюрализации и форматирование даты / числа. Однако ему не хватает встроенного обнаружения языка и не интегрируется с жизненным циклом компонентов React. Многие команды используют его в качестве полезного модуля для переводов без пользовательского интерфейса (например, в редукторах Redux или помощниках API), полагаясь на react-i18next для компонентов.

Возникает альтернатива , которая включена в экосистему Expo. Она отражает возможности реактивно-нативной локализации, но адаптирована для управляемых рабочих процессов Expo. Если вы строите с Expo, часто является самым простым способом получения данных о местоположении.

Создание многоязычного приложения: поэтапное внедрение

Давайте пройдемся по процессу добавления локализации в новый проект React Native, используя наиболее распространенный стек: react-i18next для переводов и react-native-локализовать для обнаружения местоположения устройства.

1.Установка зависимостей

Запустите следующую команду, чтобы добавить как библиотеки, так и их сверстников:

npm install react-i18next i18next react-native-localize

Если вы используете Expo, установите вместо и добавьте и пакеты.

2. Настройка i18next

Создайте файл (или для TypeScript) в корне вашего проекта. Этот файл установит экземпляр i18next, импортирует ресурсы перевода и интегрирует детектор локализации.

Ниже приведена типичная конфигурация:

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import { getLocales } from 'react-native-localize';

import en from './locales/en.json';
import es from './locales/es.json';
import fr from './locales/fr.json';
import de from './locales/de.json';

// Detect device language
const languageDetector = {
 type: 'languageDetector',
 async: false,
 detect: () => {
 const locales = getLocales();
 return locales[0]?.languageCode ?? 'en';
 },
 init: () => {},
 cacheUserLanguage: () => {},
};

i18n
 .use(languageDetector)
 .use(initReactI18next)
 .init({
 resources: {
 en: { translation: en },
 es: { translation: es },
 fr: { translation: fr },
 de: { translation: de },
 },
 fallbackLng: 'en',
 interpolation: {
 escapeValue: false, // React already safes from XSS
 },
 });

export default i18n;

Эта конфигурация использует реактивно-нативный-локализованный для извлечения основного языка устройства. Язык запасного варианта гарантирует, что отсутствующие переводы не нарушают пользовательский интерфейс.

3.Создание файлов JSON для перевода

В папке создайте отдельные файлы JSON для каждого поддерживаемого языка.

{
 "welcome": "Welcome",
 "greeting": "Hello, {{name}}!",
 "notifications": {
 "new_message": "You have {{count}} new message",
 "new_message_plural": "You have {{count}} new messages"
 }
}

{
 "welcome": "Bienvenido",
 "greeting": "¡Hola, {{name}}!",
 "notifications": {
 "new_message": "Tienes {{count}} mensaje nuevo",
 "new_message_plural": "Tienes {{count}} mensajes nuevos"
 }
}

Обратите внимание на суффикс — i18next автоматически обрабатывает формы множественного числа на основе числа, предоставленного при вызове функции перевода.

4. Оберните приложение с помощью i18next Provider

В корневом компоненте (например, ) импортируйте конфигурацию i18n и заверните все в (необязательно, но рекомендуется для тестируемости).В большинстве случаев достаточно просто импортировать , потому что регистрирует его в контексте React.

import React from 'react';
import { SafeAreaView } from 'react-native';
import './i18n'; // Ensure i18n is initialized before any component
import MainScreen from './screens/MainScreen';

const App = () => (
 <SafeAreaView style={{ flex: 1 }}>
 <MainScreen />
 </SafeAreaView>
);

export default App;

5.Использовать переводы внутри компонентов

Внутри любого функционального компонента используйте крючок для доступа к функции :

import React from 'react';
import { View, Text, Button } from 'react-native';
import { useTranslation } from 'react-i18next';

const MainScreen = () => {
 const { t, i18n } = useTranslation();

 const changeLanguage = (lng) => {
 i18n.changeLanguage(lng);
 };

 return (
 <View>
 <Text>{t('welcome')}</Text>
 <Text>{t('greeting', { name: 'Maria' })}</Text>
 <Button title="Español" onPress={() => changeLanguage('es')} />
 <Button title="Français" onPress={() => changeLanguage('fr')} />
 </View>
 );
};

export default MainScreen;

Функция автоматически переоценивает, когда язык изменяется, и компонент переосмысляется благодаря интеграции контекста React.

Расширенные возможности локализации

Помимо простого перевода ключевых значений, производственные приложения требуют поддержки плюрализма, форматирования даты / числа и адаптации макета справа налево (RTL).

Плюрализация и контекст

i18next использует формат сообщений ICU для обработки правил множественного числа. Пример выше с и демонстрирует самый простой случай. Для языков с более сложными правилами множественного числа (например, арабский, русский) вы можете предоставить дополнительные формы, такие как , , или использовать переменную внутри интерполяции.

// Example for Russian
{
 "unread_messages": "{{count}} непрочитанное сообщение",
 "unread_messages_few": "{{count}} непрочитанных сообщения",
 "unread_messages_many": "{{count}} непрочитанных сообщений"
}

Для форматирования дат и чисел вы можете либо использовать API (доступен в современных движках JavaScript), либо полагаться на библиотеку, такую как Luxon или date-fns.Обычным шаблоном является создание утилитных функций, которые принимают строку локального кода и возвращают форматированные значения, а затем используют их вместе с вашими переводами.

Поддержка правого и левого (RTL)

React Native имеет встроенную поддержку языков RTL, таких как арабский и иврит. Включите его, установив и в корневом файле, на основе текущего языка. Когда пользователь переключается на RTL-локаль, все направления флексбокса автоматически переворачиваются. Однако вы должны убедиться, что ваши стили используют логические свойства (например, вместо ), чтобы избежать жестко закодированных направлений.

import { I18nManager } from 'react-native';

// Inside your language switch handler:
if (newLanguage === 'ar') {
 I18nManager.forceRTL(true);
} else {
 I18nManager.forceRTL(false);
}

Имейте в виду, что переключение RTL требует полного перезапуска приложения на некоторых версиях Android. Вы можете предупредить пользователя или реализовать перезапуск, используя .

Лучшие практики для локализации производства

Работа с основами - это одно; создание поддерживающей, масштабируемой системы локализации - другое. Следующие лучшие практики сэкономят вам время и предотвратят расстраивающие ошибки.

Организуйте файлы перевода по функциям

Большие приложения должны избегать одного монолитного файла JSON на один язык. Вместо этого используйте функцию пространства имен i18next для разделения переводов по функциям или экранам. Например, , . Это упрощает слияние запросов на вытягивание. Загрузите пространства имен по требованию с помощью крючкового вызова .

Всегда предоставляйте язык обратной связи

Ваше приложение никогда не должно падать, потому что отсутствует ключ перевода. Определите язык запасного варианта (обычно английский), который содержит каждый ключ, используемый в приложении. Если ключ не существует на языке пользователя, i18next будет отображать значение запасного варианта. Это особенно важно во время ранней разработки, когда не все переводы завершены.

Используйте Конвенцию о ключевых именах

Общие соглашения включают использование точечных обозначений (, ) или имитации иерархии компонентов (). Ключи должны быть достаточно описательными, чтобы вы могли быстро найти их использование.

Отдельные текстовые переводы из контента

Не все, что появляется в пользовательском интерфейсе, является статичной строкой. Пользовательский контент, названия продуктов или динамические данные не должны передаваться через функцию — им нужна своя собственная логика хранения и форматирования. Храните ресурсы перевода исключительно для ярлыков приложений, ошибок и сообщений.

Автоматизация рабочих процессов перевода

Для команд с профессиональными переводчиками рассмотрите возможность интеграции с системой управления переводами (TMS), такой как Lokalise, Crowdin или Phrase. Эти платформы подключаются к вашему репозиторию кода, нажимают обновленные строки исходных кодов и вытягивают переведенные файлы. Эта автоматизация предотвращает устаревшие переводы и снижает ручные усилия.

Тестирование локализованных приложений

Тестирование многоязычных приложений требует не только проверки изменения текста. Вы должны убедиться, что все элементы настроены правильно, что макеты не ломаются, и что форматирование данных соответствует местоположению пользователя.

Моделирование различных локаций на симуляторах

Как Xcode, так и Android Studio позволяют устанавливать регион и язык устройства. Для iOS можно изменить язык в настройках Run схемы; для Android можно создать новый эмулятор с пользовательским локализацией. Тестировать каждый поддерживаемый язык на обеих платформах, чтобы выявить специфические особенности платформы (например, выборщики дат могут не уважать выбранный вами локальный язык на более старых версиях Android).

Тестовый перевод на английском языке

Напишите модульные тесты для вашей конфигурации i18n, чтобы убедиться, что все клавиши правильно разрешаются для базовых и резервных языков. Используйте тестовую структуру, такую как Jest, для загрузки конфигурации и вызова для каждого языка. Отсутствующий ключ появится в виде на выходе, что облегчит его обнаружение.

import i18n from '../i18n';

test('all translation keys exist in English', () => {
 const keys = ['welcome', 'greeting', 'notifications.new_message'];
 keys.forEach(key => {
 expect(i18n.t(key)).not.toBe(key);
 });
});

Визуальный регрессионный тест

Длинные текстовые строки на таких языках, как немецкий или финский, могут вызвать переполнение макета. Используйте тестирование снимков (например, Jest snapshots с различными конфигурациями локализации) или специальные инструменты визуальной регрессии, такие как Percy, чтобы поймать поломку пользовательского интерфейса.

Соображения в отношении эффективности

Локализация не должна ставить под угрозу производительность приложения. Вот несколько советов, чтобы сохранить ваш сайт.

Заключение

Создание многоязычного приложения React Native включает в себя больше, чем просто замена строк. Это требует продуманной архитектуры, которая обрабатывает обнаружение местоположения устройства, управление переводом, плюрализацию, форматирование чисел / дат и макет RTL. Выбирая надежную библиотеку, такую как react-i18next в сочетании с react-native-локализовать, вы можете создать опыт, который кажется родным для пользователей в каждом уголке мира.

Помните, что локализация - это непрерывный процесс - переводы нуждаются в обновлениях, могут быть добавлены новые языки, и культурные нюансы должны соблюдаться. Инвестируйте в инструменты на ранней стадии, устанавливайте четкие рабочие процессы с вашей командой переводчиков и неустанно тестируйте. Усилия окупаются в удовлетворенности пользователей, более высоком удержании и расширенном охвате рынка.

Для дальнейшего чтения, обратитесь к официальной документации react-i18next и react-native-localize. Вы также можете найти i18next список плагинов полезным для расширения функциональности.