Vai al contenuto principale

Distribuzione di librerie compatibili con l'i18n

Traduzione Beta Non Ufficiale

Questa pagina è stata tradotta da PageTurner AI (beta). Non ufficialmente approvata dal progetto. Hai trovato un errore? Segnala problema →

In applicazioni/monorepos di larga scala, non tutti i componenti/librerie risiedono nello stesso repository/progetto e potrebbero essere distribuiti diversamente. Sebbene esistano diversi approcci per risolvere questo problema, questa guida fornisce una metodologia che abbiamo visto funzionare efficacemente in grandi organizzazioni ingegneristiche.

Concetto di alto livello

Le stringhe tradotte sono essenzialmente asset, proprio come CSS, configurazioni statiche o immagini. La struttura di alto livello contiene tipicamente diversi livelli:

  • Componenti/Librerie riutilizzabili contenenti stringhe tradotte, che possono essere nidificate.

  • Applicazioni di livello superiore che consumano tali componenti/librerie.

Gerarchia di distribuzione

Ogni funzionalità/libreria sarebbe responsabile di:

Dichiarazione in package.json

Analogamente all'attributo style per il CSS, puoi dichiarare elementi come:

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

dove my-strings è la cartella contenente le stringhe tradotte nei tuoi supportedLocales:

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

L'applicazione consumatrice può scandire node_modules cercando file package.json con questi campi, aggregare le stringhe in un bundle singolo (o multipli) e servire tali JSON secondo le proprie scelte.

Questo offre flessibilità nell'output delle traduzioni in qualsiasi posizione, purché dichiarata in package.json. Tuttavia, comporta costi aggiuntivi di elaborazione a livello applicativo e può generare inconsistenza nelle posizioni di output.

Dichiarazione tramite convenzione

Simile alla Dichiarazione in package.json, ma l'output delle traduzioni è sempre in lang/{locale}.json. L'applicazione upstream può:

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

aggregare tutte le stringhe pre-tradotte delle sue librerie.

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

Questo garantisce coerenza e minimizza i costi di elaborazione dei manifest, sacrificando parte della flessibilità.

informazioni

Abbiamo osservato che l'approccio convention funziona meglio in grandi organizzazioni grazie all'imposizione di standard strutturati, mentre l'approccio manifest è più adatto ad ambienti aperti.

Passaggio dell'oggetto intl

Il nucleo di un'applicazione i18n è l'oggetto intl, contenente messaggi precompilati, impostazioni locali, formati e cache. Deve quindi essere inizializzato esclusivamente al livello superiore dell'applicazione.

Le librerie di componenti possono dichiarare intl: IntlShape come prop e propagarlo direttamente:

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>
)
}