Спросите свой вопрос и получите сводку документа, используя эту страницу и выбранного вами поставщика AI
Содержимое этой страницы было переведено с помощью ИИ.
Смотреть последнюю версию оригинального контента на английскомЕсли у вас есть идея по улучшению этой документации, не стесняйтесь внести свой вклад, подав запрос на вытягивание на GitHub.
Ссылка на документацию GitHubКопировать Markdown документа в буфер обмена
Vite i18n: особенности сборщика, а не вашего фреймворка
Большинство руководств по «Vite i18n» на самом деле представляют собой статьи по React или Vue, в которых случайно используется Vite. Этот материал посвящен уровню ниже: как импортируются каталоги, что с ними делает Rollup и почему написанная вами ленивая загрузка (lazy loading), скорее всего, таковой не является.
Содержание
Статический импорт по умолчанию синхронен и жаден
Самая базовая конфигурация импортирует все каталоги в верхней части модуля:
Копировать код в буфер обмена
Это помещает все три каталога в начальный чанк точки входа, на каждой странице, для каждого посетителя. Это допустимо для двух языков и сотни строк. При десяти языках это превращается в самую тяжелую предотвратимую статью расходов в вашем бандле.
import.meta.glob и флаг, в котором все ошибаются
Glob-импорт в Vite обычно решает эту проблему:
Копировать код в буфер обмена
Ленивая загрузка включена по умолчанию: каждая запись представляет собой функцию, возвращающую динамический импорт, и Rollup генерирует отдельный чанк на каждый файл. Флаг { eager: true }, напротив, встраивает все файлы непосредственно в импортирующий модуль, полностью перечеркивая оптимизацию:
Копировать код в буфер обмена
Ловушка в том, что оба варианта работают в dev-режиме, поскольку Vite отдает модули без бандлинга. Разница проявляется только в каталоге dist. Проверьте сборку через npx vite build && npx vite preview и посмотрите, что реально входит во входной чанк.
Разделение по роутам редко разделяет каталоги на практике
Это поведение часто застает разработчиков врасплох. Вы раскладываете каталоги по страницам:
Копировать код в буфер обмена
Затем два разных маршрута импортируют checkout.json, и Rollup выносит его в общий разделяемый чанк, который скачивается на обоих маршрутах. Алгоритм чанкинга Rollup опирается на граф модулей, а не на структуру папок: любой модуль, доступный более чем из одной точки входа, становится общим. Добавление третьего маршрута ничего не изменит, а четвертый может перекроить чанки совершенно неожиданно.
Таким образом, разделение по роутам работает только тогда, когда графы импорта страниц строго изолированы. Если размер бандла критичен, проверяйте его объективно:
Копировать код в буфер обмена
Если нужно жестко зафиксировать границы чанков, воспользуйтесь build.rollupOptions.output.manualChunks, расплачиваясь за это ручной поддержкой конфигурации.
Каталоги не поддерживают Hot Module Replacement (HMR)
Меняете компонент — Vite мгновенно обновляет его. Меняете locales/fr.json — и в зависимости от способа импорта ничего не происходит. Динамически импортируемый JSON не имеет встроенной HMR-границы, поэтому граф модулей не знает, как инвалидировать зависимые компоненты.
Разработчики часто обходят это постоянным перезапуском сервера разработки при каждой правке текста. Решение лежит на стороне i18n-плагина: он обязан перехватывать HMR-обновление и проталкивать свежие сообщения в работающее приложение. Выбирая библиотеку, проверьте, умеет ли ее плагин для Vite обрабатывать HMR для словарей.
define намертво зашивает локаль в билд
Возникает соблазн определить локаль по умолчанию на этапе сборки:
Копировать код в буфер обмена
Конструкция define производит чистую текстовую подстановку во время компиляции. Значение, зашитое при сборке, становится окончательным, что вынуждает делать отдельный билд под каждый язык. Это легитимный подход, именно так устроена нативная интернационализация в Angular, но он не подходит, если единый деплой должен обслуживать все языки одновременно.
Значения, которые должны варьироваться для каждого запроса, нельзя выносить в define, их необходимо вычислять в рантайме.
Перенос парсинга сообщений на этап сборки
Все зрелые решения в экосистеме приходят к одному итогу: перестать парсить сообщения в браузере.
Открыть таблицу в модальном окне для четкого просмотра всех данных
| Плагин | Что выносится на этап сборки |
|---|---|
@intlify/unplugin-vue-i18n | Компилирует сообщения vue-i18n в render-функции (рантайм без парсера) |
| Lingui (макрос + плагин) | Извлекает и компилирует каталоги, заменяет макросы на ID сообщений |
| Paraglide (inlang) | Компилирует каждое сообщение в отдельную tree-shakable функцию |
vite-intlayer | Собирает словари компонентов, удаляет и минифицирует неиспользуемое |
Выгода здесь двоякая: из клиентского бандла полностью исчезает компилятор сообщений, а неиспользуемые строки могут быть удалены статически. Сопутствующая цена: и dev-сервер, и CI обязаны использовать плагин, а запуск чистого tsc или тестов вне Vite потребует дополнительной настройки.
vue-i18n — наглядный пример: без @intlify/unplugin-vue-i18n вы поставляете в продакшен компилятор, дергающий new Function, что ведет к лишнему весу и конфликтам с Content Security Policy (CSP).
SSR: никогда не храните локаль в переменных модуля
При использовании SSR (через фреймворк или vite-plugin-ssr) действует строгое правило: переменная на уровне модуля, хранящая текущую локаль, становится общей для всех одновременных запросов в рамках процесса сервера.
Копировать код в буфер обмена
Два пользователя, одновременно зашедшие на сервер, попадут в состояние гонки, и один из них получит страницу на языке другого. В локальной разработке это незаметно, так как вы тестируете приложение в одиночку. Всегда определяйте локаль для каждого запроса индивидуально и передавайте ее явно через контекст или request-local хранилище фреймворка.
Плагин Vite для Intlayer
Intlayer подключается одним плагином, который берет на себя компиляцию словарей, наблюдение за файлами в dev-режиме и оптимизацию:
Копировать код в буфер обмена
Перезапись импортов, очистка (purge) и минификация включены по умолчанию. Два главных флага настраиваются в intlayer.config.ts:
Копировать код в буфер обмена
Поскольку контент объявляется рядом с компонентами, а не в циклопических файлах локалей, шаг очистки оперирует реальным графом модулей, что делает удаление лишнего кода безопасным. Ограничение то же: плагин обязателен везде, где компилируется код, включая CI и тесты. Подробнее в статье об оптимизации бандла.
Распространенные ошибки
{ eager: true }для импорта, задуманного как ленивый. Работает в dev, но тянет все языки в продакшен.- Ожидание, что структура папок формирует чанки. Rollup анализирует граф импортов, а не папки. Анализируйте реальный билд.
- Перезапуск dev-сервера при правках текста. Признак отсутствия поддержки HMR в выбранном решении.
- Фиксация локали через
define. Привязывает вас к отдельной сборке на каждый язык. - Хранение локали в модуле при SSR. Приводит к утечке данных между запросами пользователей.
- Оценка размера бандла по dev-серверу. Несобранные модули не имеют отношения к продакшен-бандлу.
Полезные материалы
- Оптимизация бандла: purge, минификация и что попадает в браузер
- Отчеты производительности фреймворков
- Справочник конфигурации
- Настройка Intlayer с Vite и React
- Адаптер совместимости i18next
- React i18n: как работает модель провайдеров
- Vue i18n: принцип работы и слабые места
- i18n на уровне компонентов против централизованной схемы
Комментарии
Пока нет комментариев. Будьте первым, кто поделится своими мыслями.
