Как локализовать Vue.js приложение

0b85f64ba204751d2b4b7b96d565ed9c.jpg

Инструменты

  1. Vue.js вместе с Vue CLI.

  2. vue-i18n

  3. VSCode

  4. BabelEdit

Vue.js вместе с Vue CLI

Для тех кто не знает как работать с Vue CLI вот документация. Если кратко, то для установки нам нужно ввести две команды npm:

npm install -g @vue/cli  //Установка

vue create test-project  //Создание проекта

vue-i18n

Пакет для локализации. Для установки нужно ввести команду:

npm install vue-i18n

Следующим шагом в корне проекта создаем папку locales с файлами .json (например: ru.json, en.json…). Здесь мы будем сохранять ключи и значения к отдельному языку. Ключи во всех файлах одинаковы, а значения переведены под конкретный язык.

Далее создаем папку helpers так же в корне проекта, в ней создаем файл i18n.js. Он нужен нам для определения языка на момент загрузки приложения, и для подгрузки наших json ключей в JavaScript. В созданный файл копируем следующий код:

import Vue from "vue";
import VueI18n from "vue-i18n"; //Импорт установленного пакета

Vue.use(VueI18n);

function loadLocaleMessages() {
  const locales = require.context(
    "@/locales", // Путь к папке с нашими json файлами локализации
    true,
    /[A-Za-z0-9-_,\s]+\.json$/i
  );
  const messages = {};
  locales.keys().forEach(key => {
    const matched = key.match(/([A-Za-z0-9-_]+)\./i);
    if (matched && matched.length > 1) {
      const locale = matched[1];
      messages[locale] = locales(key);
    }
  });
  return messages;
}
function checkDefaultLanguage() { //Определяем язык браузера
  let matched = null;
  let languages = Object.getOwnPropertyNames(loadLocaleMessages());
  languages.forEach(lang => {
    if (lang === navigator.language) {
      matched = lang;
    }
  });
  if (!matched) {
    languages.forEach(lang => {
      let languagePartials = navigator.language.split("-")[0];
      if (lang === languagePartials) {
        matched = lang;
      }
    });
  }
  return matched;
}
export const selectedLocale = localStorage.getItem('locale') 
															|| checkDefaultLanguage()
															|| "ru";
export const languages = Object.getOwnPropertyNames(loadLocaleMessages());
export default new VueI18n({
  locale: selectedLocale || "ru",
  globalInjection: true,
  fallbackLocale: "ru",
  messages: loadLocaleMessages()
});

Следующим шагом нужно импортировать созданный файл в main.js:

import Vue from 'vue'
import router from './router/router.js'
import App from './App.vue'
import store from './store/store.js'

import i18n from "./helpers/i18n.js"

new Vue({
  store,
  router,
  i18n,
  render: h => h(App),
}).$mount('#app')

Наш i18n теперь подключен, остается сделать переключатель языка. Тут уже кто на что горазд, я сделал обычным селектом и добавил в vuex стор файл locale.js в котором импортировал файл i18n.js из нашей папки helpers. Сам код из стора:

import Vue from 'vue';
import Vuex from 'vuex';
import i18n, { selectedLocale } from 'src/helpers/i18n';

Vue.use(Vuex);

export default{
    state: {
      locale: selectedLocale
    },
    getters: {
      getLocale: state => state.locale
    },
    mutations: {
      updateLocale(state, newLocale) {
        i18n.locale = newLocale // важно оставить, что б менялся язык
        state.locale = newLocale // а здесь меняем значение для переключателя
        localStorage.setItem('locale', newLocale); // запоминаем текущий язык, что б после перезагрузки страницы не сбросило на стандартный        
      }
    },
}

Ну и сам селект:

export default { 
  computed: {
    lang: {
      get() {
        return this.$store.getters.getLocale;
      },
      set(newValue) {
        this.$store.commit("updateLocale", newValue);
      }
    }
  }
}

Как вы могли заметить $t обращается по названию ключа к i18n и показывает значение, так и происходит локализация. Главное в каждом json файле заполнить все ключи. А для того что бы самому не вводить каждый раз ключ вручную есть у VSCode отличный плагин i18n-Ally.

VSCode

Плагин i18n-Ally позволяет автоматически создавать ключи из hard coded строк, переводить значения с помощью переводчика, и автозаполнять строку нужным вызовом функции ($t (…), this.$t (…) и т.д.) Загрузить его можно здесь. Документация тут. Примеры можно посмотреть на странице документации.

У меня возникла проблема когда проект сделан и его нужно перевести. Перелопатить каждый компонент задача не из интересных да и времени не так что б много. Хорошо что контент заполнялся на русском языке и его можно отличить при глобальном поиске (Ctrl + Shift + F) от кода и разметки. Так я и зделал, прописал регулярное выражение:

[а-яА-Я]+

ef87684c7b9d7571239bb87ca5cbeeb6.jpg

Немного трудозатратно конечно, но для меня это единственный нормальный рабочий способ. В интернете есть способы том как автоматически собрать hard coded строки, но мне они не подошли. То вылезал null то ключ не так задавал, то разрывал строку. Вобщем пришел к такому решению.

BabelEdit

Для повседневной работы i18n-Ally должно хватить с головой. Но когда нужно сразу перевести 300–500 ключей то у меня вылезла ошибка 429 с ограничением запросов на гугл переводчик. Здесь то нам и пригодится BabelEdit, у него есть пробная лицензия которую путем нехитрых гуглений можно продлить легально. Про него достаточно понятно написано в документации, не буду тут повторять, единственное я просто сохранил .babel проект в корень приложения. Документация и загрузка доступна по ссылке здесь.

© Habrahabr.ru