nanostores / i18n

A tiny (≈600 bytes) i18n library for React/Preact/Vue/Svelte
MIT License
229 stars 12 forks source link

Add partial translation loading #3

Closed ai closed 2 years ago

ai commented 2 years ago

Now I18n downloads the whole translation JSON for specific locale.

get (locale) {
   return fetch(`/translations/${locale}.json`)
}

But many application parts are rarely used. It could be nice to have tree-shaking analog.

For instance, we use components name like main/post or settings/user. Then during the rendering we will collect all components names and send them to get. In this example, get will load translation for translations/ru/main.json and trabslations/settings/ru.json

get (locale, components) {
   return Promise.all(
    components
      .map(name => name.split('/')[0])
      .unique()
      .map(chunk => fetch(`/translations/${locale}/${chunk}.json`))
  )
}
yunusga commented 2 years ago

C SSR проблем с частичной загрузкой не будет т.к. есть моментальный доступ к файловой системе и можно принимать решения в зависимости от обстоятельств запроса и наличия перевода для требуемого языка.

Как быть на фронте:

  1. Когда необходимо будет загрузить переводы для нескольких компонентов (это несколько запросов за переводами)?
  2. Отравлять ещё один запрос за переводом по умолчанию в случае если нет перевода компонента для требуемого языка?

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

ai commented 2 years ago

Отравлять ещё один запрос за переводом по умолчанию в случае если нет перевода компонента для требуемого языка?

Перевод по умолчанию (base) всегда есть в коде компонента, так как с помощью него объявляются типы (через вызов i18n(componentName, baseTranslation)).

Когда необходимо будет загрузить переводы для нескольких компонентов (это несколько запросов за переводами)?

Нужно собирать имена всех компонентов, которые надо рендерить на странице и только потом отправлять запрос

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

Можно сделать гораздо проще — на этапе сборке объединять переводы в большие JSON-файлы.

Например, разработчик может называть свои компоненты как main/header, main/home, settings/user. А потом на этапе сборке объединять все main/* и settings/*. Соответственно в get() можно посылать запрос по префиксу в имени компонента.

Учти только, что при выполнении get ('ru', ['main/home']) функция может вернуть переводы не только для main/home, но и для main/header который сейчас может быть не нужен (или же был запрошен отдельный запросом). К этому надо быть готовым (хотя 2 запроса не страшно, если они идут редко).