Библиотека NPM для интернационализации и локализации i18n очень популярен, но в последние годы он сильно вырос. Он имеет множество функций для локализации дат, чисел, множественного числа, двунаправленных алфавитов, загрузки локалей с сервера и множества других вещей. На сайте i18next это уже называетсярамки интернационализации“.

вплоть до точки

Новый авиалайнер. Хозяйка входит в каюту:

— Вы на нашем новом авиалайнере. У нас есть кинозал в носу самолета, зал игровых автоматов в хвосте, бассейн на нижней палубе и сауна на верхней палубе. А теперь, дамы и господа, пристегните ремни, и мы попробуем взлететь со всем этим дерьмом.

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

В частности, мне лично нужно:

  1. Поиск перевода по составному ключу –t("finance.transactions.deposit")

  2. Перевод с параметром – t("hello-message", "Вася")

  3. Таблицы для списков или абзацев текста

На примере Vue 3 я покажу вам, как избавиться от i18next без потери функциональности в этом случае, не только за счет облегчения js бандла, но и за счет сокращения кода, при этом сохраняя отзывчивость (смена языка сайта на лету)

Простота и элегантность рефакторинга, описанного ниже, будут обеспечены Vue 3 Composition API, но в целом этот метод подойдет для любого адаптивного фреймворка.

Ваш i18n

Вот чистая реализация вышеуказанного функционала в 30 строк против полутора мегабайт без всяких зависимостей — https://stackblitz.com/edit/i18n-detox?file=src%2FApp.vue

Проект Vue 3 с i18next

По умолчанию в проекте с API композиции подключение и использование i18next происходит так

Для
// main.js
import { i18n, useI18n } from  "@/app/composables/i18n";
const { initI18n } =  useI18n();

initI18n();
app.use(i18n);


// useI18n.js
import { ref } from  "vue";
import { api } from  "@/services";
import { createI18n } from  "vue-i18n";
const  locales  = [
  {
   code:  "en",
   name:  "English",
   flag:  "england",
  },
  {
   code:  "ru",
   name:  "Pусский",
   flag:  "russian",
  },
];
const locale  =  ref();
export const i18n  =  createI18n({
 I18nScope:  "global",
 globalInjection:  true,
 legacy:  false,
 allowComposition:  true,
 fallbackLocale:  import.meta.env.VITE_I18N_FALLBACK_LOCALE  ||  "en",
 formatFallbackMessages:  true,
});

export  function  useI18n() {
  
 function  initI18n() {
   const  lang  =
   localStorage.getItem(import.meta.env.VITE_APP_NAME  +  "_lang") ??
        (import.meta.env.VITE_DEFAULT_LOCALE  ||  "en");
   loadLanguage(lang);
  }
  
 async  function  loadLanguage(lang) {
   if (i18n.global.locale  !==  lang) {
     locale.value  =  locales.find((l) =>  l.code  ===  lang);
     const  data  =  await  api.utils.downloadLanguage(lang);
     i18n.global.setLocaleMessage(lang, data[lang]);
     i18n.global.locale.value  =  lang;
     localStorage.setItem(import.meta.env.VITE_APP_NAME  +  "_lang", lang);
    }
  }
 return {
   i18n,
   locale,
   locales,
   initI18n,
   loadLanguage,
  };
};


// Использование в компонентах Composition API
import { useI18n } from  "vue-i18n";
const { t } =  useI18n();
t("finance.transactions.deposit"),

// Использование в js файлах
import { i18n } from  "@/app/composables/i18n";
i18n.global.t("finance.transactions.deposit")

Все, что вам нужно, чтобы избавиться от i18nextзаключается в явном определении объекта messages чтобы сохранить все локали и добавить в useI18n() реактивная функция t()который будет просто обрабатывать составной ключ, параметр и массив.

ЧИТАТЬ   С 2024 года увеличатся налоговые отчисления на образование и зарплату

После этого вы можете прокомментировать все использование библиотеки vue-i18n

После
// main.js
import { useI18n } from  "@/app/composables/i18n";
const { initI18n } =  useI18n();

initI18n();
// app.use(i18n);


// useI18n.js
import { ref } from "vue";
import { api } from "@/services";

// import { createI18n } from "vue-i18n";

const locales = [
  {
    code: "en",
    name: "English",
    flag: "england",
  },
  {
    code: "ru",
    name: "Pусский",
    flag: "russian",
  },
];
// export const i18n = createI18n({
//   I18nScope: "global",
//   globalInjection: true,
//   legacy: false,
//   allowComposition: true,
//   fallbackLocale: import.meta.env.VITE_I18N_FALLBACK_LOCALE || "en",
//   formatFallbackMessages: true,
//   // messages: { en: messages }
// });

const locale = ref();
let messages;

// Делаем доступ для использования в js модулях
export const t = useI18n().t;

export function useI18n() {
  function initI18n() {
    messages = [];
    const lang =
      localStorage.getItem(import.meta.env.VITE_APP_NAME + "_lang") ??
      (import.meta.env.VITE_APP_DEFAULT_LOCALE || "en");
    loadLanguage(lang);
  }

  async function loadLanguage(lang) {
    if (locale.value !== lang) {
      const localeMessages = await api.utils.downloadLanguage(lang);
      messages[lang] = localeMessages[lang];
      locale.value = locales.find((l) => l.code === lang);
      // i18n.global.setLocaleMessage(lang, localeMessages[lang]);
      // i18n.global.locale.value = lang;
      localStorage.setItem(import.meta.env.VITE_APP_NAME + "_lang", lang);
    }
  }

  function t(msg, param = null) {
    let val = msg.split(".").reduce((val, part) => val[part], messages[locale.value.code]);
    if (param) {
      val = val.replace("{0}", param);
    }
    return val;
  }

  return {
    t,
    // i18n,
    locale,
    locales,
    initI18n,
    loadLanguage,
  };
}


// Использование в компонентах Composition API
import { useI18n } from  "@/app/composables/i18n";
const { t } =  useI18n();
t("finance.transactions.deposit"),

// ИЛИ

import { t } from  "@/app/composables/i18n";
t("finance.transactions.deposit")

// Использование в js файлах
import { t } from  "@/app/composables/i18n";
t("finance.transactions.deposit")

В этом примере перевод для определенной локали загружается с сервера по запросу, но объект messages вы можете иметь на клиенте немедленно

А.к.а export const t = useI18n().t; позволяет использовать тот же синтаксис в компонентах и ​​модулях js.

I18следующие расширения

ты I18next есть расширение для `Vue DevTools` (довольно бесполезное), а есть расширение I18следующий союзник для кода MS VS (очень полезно). так вот I18next Ally работает с новой реализацией, если package.json содержит пакет vue-i18n в зависимостях (нет необходимости включать его в код). Я рекомендую. Однако оба расширения потребляют много ресурсов, поэтому лучше использовать их по мере необходимости.

ЧИТАТЬ   Задержан один из подозреваемых участников нападения на пост ГИБДД в Ингушетии.

Общий

Мы закомментировали больше строк, чем добавили, а размер пакета JavaScript после сборки уменьшился на 50 КБ, функциональность осталась. Реагент.

До (vue 3, vue-router, тостер, vue-i18n)

f6146f13d051fbca870e67756b1361e7

После (vue 3, vue-router, тостер)

e0bfbc2eea62a11117d695bf2a8076e2

Спасибо, I18next, и до свидания.

Другой мой пост на эту тему — «Работа с i18n — автоматизация Google Translate и другие полезные советы».

Source

От admin