Skip to content

Плагины Vite

Vite-плагин — проверка полноты переводов

Проверяет все JSON-файлы локалей относительно референсной локали и сообщает об отсутствующих или лишних ключах. Запускается при buildStart и при каждом сохранении файла локали во время разработки (HMR).

ts
// vite.config.ts
import { vueI18nCheckPlugin } from 'vue-i18n-kit/vite'

export default defineConfig({
  plugins: [
    vue(),
    vueI18nCheckPlugin({
      localesDir: 'src/locales',
      defaultLocale: 'en',
      failOnMissing: true,
    }),
  ],
})

Опции

ОпцияТипПо умолчаниюОписание
localesDirstring'src/locales'Директория с JSON-файлами локалей относительно корня проекта Vite.
defaultLocalestringпервый файл по алфавитуЛокаль, используемая как референс при сравнении ключей.
failOnMissingbooleanfalseКогда true, отсутствующие ключи прерывают сборку с ошибкой.

Пример вывода

[vue-i18n-kit] Incomplete translations detected (reference: "en"):
  Locale "ru":
    Missing keys (2):
      - buttons.cancel
      - profile.title
  Locale "de":
    Missing keys (1):
      - profile.title
    Extra keys (1):
      + legacy.old_key

Vite-плагин — встроенные переводы

vueI18nInlinePlugin встраивает все JSON-файлы локалей в продакшен-бандл на этапе сборки через виртуальный модуль. HTTP-запросов во время выполнения нет — переводы это обычный JavaScript-объект, встроенный в бандл.

Идеально подходит для: SSR-приложений, offline-совместимых PWA, небольших проектов, где размер бандла менее важен, чем задержка загрузки.

ts
// vite.config.ts
import { vueI18nInlinePlugin } from 'vue-i18n-kit/vite'

export default defineConfig({
  plugins: [
    vue(),
    vueI18nInlinePlugin({
      locales: {
        en: 'src/locales/en.json',
        ru: 'src/locales/ru.json',
        de: 'src/locales/de.json',
      },
    }),
  ],
})

Использование в приложении

ts
import inlineLocales from 'virtual:vue-i18n-kit/locales'

app.use(
  createVueI18nPlugin({
    defaultLocale: 'en',
    locales: {
      en: { messages: inlineLocales.en, meta: { display: 'English' } },
      ru: { messages: inlineLocales.ru, meta: { display: 'Русский' } },
    },
  }),
)

TypeScript — добавьте в env.d.ts или vite-env.d.ts:

ts
declare module 'virtual:vue-i18n-kit/locales' {
  const locales: Record<string, Record<string, unknown>>
  export default locales
}

Vite-плагин — разделение кода по неймспейсам

vueI18nNamespacePlugin сканирует директорию с разбитыми файлами локалей и генерирует виртуальный модуль virtual:vue-i18n-namespaces. Модуль экспортирует объект locales, готовый для передачи в createVueI18nPlugin — каждая запись локали включает динамические вызовы import() по неймспейсам, так что Vite автоматически разбивает их на отдельные чанки.

ts
// vite.config.ts
import { vueI18nNamespacePlugin } from 'vue-i18n-kit/vite'

export default defineConfig({
  plugins: [
    vue(),
    vueI18nNamespacePlugin({
      dir: 'src/locales/split',
      locales: {
        en: { meta: { display: 'English', flag: '🇬🇧' }, eagerNamespaces: ['common'] },
        ru: { meta: { display: 'Русский', flag: '🇷🇺' }, eagerNamespaces: ['common'] },
      },
    }),
  ],
})

Использование в приложении

ts
import { locales } from 'virtual:vue-i18n-namespaces'

app.use(createVueI18nPlugin({ defaultLocale: 'en', locales }))

Неймспейсы, не входящие в eagerNamespaces, загружаются лениво через useNamespace():

ts
const { isLoading } = useNamespace('dashboard')
// или несколько сразу:
const { isLoading } = useNamespace(['dashboard', 'charts'])

Опции

ОпцияТипПо умолчаниюОписание
dirstring'src/locales/split'Директория, содержащая поддиректории локалей (<dir>/<locale>/<namespace>.json).
localesRecord<string, { meta?, eagerNamespaces? }>{}Конфигурация по локалям. Локали, найденные в директории, но не перечисленные здесь, включаются автоматически.

HMR: при изменении любого JSON-файла неймспейса внутри dir Vite автоматически инвалидирует и перезагружает виртуальный модуль.

Vite-плагин — редактор перевода в контексте (только dev)

vueI18nDevPlugin внедряет плавающий оверлей редактора в работающее приложение во время разработки. Переведённые строки можно обернуть компонентом <I18nInspect>, чтобы показывать значок карандаша при наведении; клик по нему открывает встроенный попап для редактирования этого ключа.

Плагин полностью не действует при продакшен-сборках.

ts
// vite.config.ts
import { vueI18nDevPlugin } from 'vue-i18n-kit/vite'

export default defineConfig({
  plugins: [
    vue(),
    vueI18nDevPlugin(), // uiUrl устанавливается автоматически через vue-i18n-kit dev
  ],
})

Запустите оба сервера одной командой:

bash
npx vue-i18n-kit dev

Это автоматически определяет scripts.dev из package.json, запускает Vite и UI редактора локалей параллельно и связывает их автоматически.

Автообёртка (по умолчанию)

По умолчанию vueI18nDevPlugin автоматически переписывает шаблоны Vue SFC во время разработки. Каждая интерполяция {{ t('key') }}, {{ tm('key') }} и {{ $t('key') }} оборачивается в <I18nInspect>ручная разметка не нужна.

vue
<!-- Исходный код как написан -->
<template>
  <p>{{ t('nav.home') }}</p>
</template>

<!-- Что реально компилирует Vite в dev-режиме -->
<template>
  <p>
    <I18nInspect i18n-key="nav.home">{{ t('nav.home') }}</I18nInspect>
  </p>
</template>

Установите autoWrap: false, чтобы вместо этого использовать явную разметку <I18nInspect i18n-key="…"> или директиву v-i18n-inspect.

Динамические ключи — директива v-i18n-inspect

Для runtime-ключей (переменные, вычисляемые значения, индексы циклов) используйте директиву, которая прикрепляет поведение при наведении к существующему элементу без добавления обёрточного узла:

vue
<span v-i18n-inspect="activeKey">{{ t(activeKey) }}</span>
<span v-i18n-inspect="`items.${item.id}`">{{ t(`items.${item.id}`) }}</span>

Опции

ОпцияТипПо умолчаниюОписание
uiUrlstringenv I18N_KIT_UI_URL или 'http://localhost:4173'URL работающего сервера vue-i18n-kit ui.
autoWrapbooleantrueАвтоматически оборачивать интерполяции t() / tm() / $t() в <I18nInspect> во время разработки.
wrapFunctionsstring[]['t', 'tm', '$t']Имена функций для поиска, когда autoWrap включён.
iframeWidthstring'480px'Ширина правой панели iframe-редактора.