Fala, comunidade dev! 👋
Nesta jornada modernizando o nosso YMS, já passamos por performance, estrutura de pastas e padrões de código. Mas quando falamos de sistemas Enterprise, um requisito não-funcional frequentemente assombra as equipes de Front-end: a Internacionalização (i18n).
Muitos tutoriais ensinam a traduzir um botão de "Salvar" para "Save". Mas na trincheira de um sistema logÃstico real e de grande porte, as coisas são muito mais complexas. Não se trata apenas de traduzir palavras, mas de definir como essa tradução será processada na arquitetura da aplicação.
1. O Desafio Numérico (Muito além do texto)
Antes de falar de bibliotecas de tradução, precisamos lembrar que i18n afeta a matemática da tela. O peso de um caminhão no Brasil é 45.500,00 kg. Nos EUA, precisa ser renderizado obrigatoriamente como 45,500.00 kg. Uma vÃrgula no lugar errado em um sistema logÃstico gera multas milionárias nas rodovias.
Felizmente, aproveitando os Pipes nativos (DecimalPipe e DatePipe) combinados com a injeção do LOCALE_ID correto na inicialização da aplicação, o Angular resolve isso sozinho:
<span>Peso Lido: {{ pesoTotalCapturado | number:'1.2-2' }}</span>
<span>Data: {{ momentoPesagem | date:'short' }}</span>
2. O Dilema Arquitetural: Runtime vs. Build-time
Quando fomos refatorar a tradução dos textos e labels do sistema, esbarramos na grande dúvida: Abraçar o nativo @angular/localize ou utilizar bibliotecas de terceiros?
Para entender a nossa decisão, precisamos separar as abordagens em duas categorias:
A. Tradução em Tempo de Build (AOT) - @angular/localize
A solução nativa do Angular é fantástica para a performance da tela, pois ela embute os textos direto no HTML. Mas ela faz isso gerando uma versão inteira do sistema para cada idioma durante o ng build.
- O Problema no YMS: Se temos 3 idiomas (PT, EN, ES), o nosso tempo de build no CI/CD triplica. Para um sistema gigante, gerar e hospedar múltiplas pastas de build (uma para cada lÃngua) começou a travar a nossa esteira de deploy. Além disso, a troca de idioma exigia o recarregamento total da página.
B. Tradução em Tempo de Execução (Runtime) - `@jsverse/transloco`
Foi aqui que a biblioteca Transloco brilhou para nós. Ela carrega arquivos JSON com as traduções enquanto o usuário navega.
- A Vitória da Manutenção: Com o Transloco, nós fazemos apenas um build. A grande sacada arquitetural dessa biblioteca são os Escopos (Lazy Load Scopes). Se o usuário acessa o módulo de Balança, o Transloco não baixa o dicionário do sistema inteiro; ele baixa apenas um micro-JSON de 2KB exclusivo daquela tela. O impacto na performance de rede é mÃnimo, a troca de idioma é em tempo real, e a nossa esteira de CI/CD agradece.
3. Na Prática: Escrevendo código com o Transloco
O Transloco nos oferece uma Developer Experience (DX) incrÃvel, permitindo usar Pipes ou diretivas estruturais, mantendo o HTML limpo e otimizado.
No HTML:
Em vez de usar Pipes isolados para cada palavra (o que força o Angular a criar múltiplas inscrições por baixo dos panos), usamos a diretiva estrutural *transloco. Ela injeta a função de tradução apenas naquele bloco:
<ng-container *transloco="let t; read: 'balanca'">
<button class="btn-primary">
{{ t('btnConfirmarPesagem') }}
</button>
<p>
{{ t('msgFila', { qtdCaminhoes: 5 }) }}
</p>
</ng-container>
No TypeScript:
Para casos onde o texto precisa nascer dentro do código (como notificações de Toast dinâmicas ou mensagens de validação vindas da API), injetamos o TranslocoService:
import { Component, inject } from '@angular/core';
import { MessageService } from 'primeng/api';
import { TranslocoService } from '@jsverse/transloco';
@Component({ ... })
export class OperacaoComponent {
private messageService = inject(MessageService);
private translocoService = inject(TranslocoService);
finalizarOperacao() {
// Buscando a tradução em tempo real no TypeScript
const msgSucesso = this.translocoService.translate('operacao.toastSucesso');
this.messageService.add({ severity: 'success', detail: msgSucesso });
}
}
Conclusão
O nativo @angular/localize é o rei da performance absoluta de renderização. Porém, para o nosso cenário corporativo, o Transloco entregou o equilÃbrio perfeito: resolveu o gargalo do nosso tempo de build no CI/CD, evitou a complexidade de gerenciar múltiplos deploys e manteve a performance da aplicação alta graças ao carregamento sob demanda (Lazy Loading) dos dicionários.
No nosso nono e último artigo da série, vamos fechar com chave de ouro falando sobre UX Corporativa: como implementamos o tão pedido Dark Mode e dominamos as customizações de Grids pesadas do PrimeNG.
E vocês, preferem o modelo em tempo de execução (Transloco/ngx-translate) ou já adotaram o empacotamento em tempo de build do Angular? Conta aà nos comentários! 👇
Top comments (0)