Ir para o conteúdo principal

Distribuindo bibliotecas compatíveis com i18n

Tradução Beta Não Oficial

Esta página foi traduzida por PageTurner AI (beta). Não é oficialmente endossada pelo projeto. Encontrou um erro? Reportar problema →

Em aplicações/monorepositórios de grande escala, nem todos os componentes/bibliotecas residem no mesmo repositório/projeto e podem ser distribuídos de forma diferente. Embora existam múltiplas formas de resolver este problema, este guia apresenta uma abordagem que observamos funcionar bem em grandes organizações de engenharia.

Conceito de alto nível

Strings traduzidas são basicamente ativos, assim como CSS, configuração estática ou imagens. A estrutura de alto nível geralmente contém várias camadas:

  • Componentes/Bibliotecas reutilizáveis que contêm strings traduzidas, podendo ser aninhados.

  • Aplicações de nível superior que consomem esses componentes/bibliotecas.

Hierarquia de Distribuição

Cada funcionalidade/biblioteca seria responsável por:

Declaração no package.json

Isso é semelhante ao uso do atributo style para declarar CSS. Você pode declarar algo como:

{
"name": "my-library",
"version": "1.0.0",
"lang": "my-strings",
"supportedLocales": ["en", "en-GB", "ja"]
}

onde my-strings é a pasta contendo suas strings traduzidas nos seus supportedLocales:

my-strings
|- en.json
|- en-GB.json
|- ja.json

A aplicação consumidora pode percorrer node_modules buscando arquivos package.json com esses campos e agregar as strings em um único bundle (ou múltiplos bundles), servindo esses JSON conforme escolher.

Isso oferece flexibilidade para gerar traduções em qualquer local desejado, desde que declarado no package.json. Entretanto, também acarreta custo adicional de processamento no nível da aplicação e incentiva inconsistência no local de saída.

Declaração por convenção

Similar à Declaração no package.json, mas as traduções são sempre geradas em lang/{locale}.json. A aplicação principal pode:

formatjs compile "node_modules/**/lang/en.json" --ast --out-file lang/en.json

para agregar todas as strings pré-traduzidas de suas bibliotecas.

my-lib
|- src
|- lang
|- en.json
|- en-GB.json
|- ja.json
|- node_modules
|- library1
|- lang
|- en.json
|- en-GB.json
|- ja.json
|- library2
|- lang
|- en.json
|- en-GB.json
|- ja.json

Isso garante consistência e minimiza o custo de processamento de diferentes manifestos, mas é menos flexível.

informação

Observamos que a abordagem por convention funciona melhor em grandes organizações devido à imposição de padrões, enquanto a abordagem por manifest se adapta melhor a ambientes mais abertos.

Passando o objeto intl

O núcleo de uma aplicação i18n é o objeto intl, que contém mensagens pré-compiladas, configurações de locale, formatos e cache. Portanto, ele deve ser inicializado apenas no nível superior da aplicação.

Bibliotecas de componentes podem declarar intl: IntlShape como prop e subsequentemente repassá-lo diretamente como:

import {IntlShape} from 'react-intl'
import {MyButton, MyForm} from 'my-components'
interface Props {
intl: IntlShape
}

function MyFeature(props: Props) {
return (
<div>
<MyButton intl={props.intl} />
<MyForm intl={props.intl} />
</div>
)
}

or passing down via context using RawIntlProvider:

import {IntlShape, RawIntlProvider} from 'react-intl'
import {MyButton, MyForm} from 'my-components'
interface Props {
intl: IntlShape
}

function MyFeature(props: Props) {
return (
<RawIntlProvider value={props.intl}>
<MyButton />
<MyForm />
</RawIntlProvider>
)
}