Existe uma categoria de problema em aplicação React que só aparece depois da publicação: funciona perfeitamente na máquina de quem desenvolveu e quebra, ou se comporta de forma estranha, no ambiente real.
Uma variável que aponta para o endereço errado. Um usuário vendo a versão antiga do site horas depois da atualização. Uma chave de API visível para qualquer pessoa que abra as ferramentas do navegador.
Nenhum desses é bug do React. Todos vêm da diferença entre o que acontece no desenvolvimento e o que acontece no build de produção — um processo que transforma o seu código em arquivos, e que tem regras próprias que precisam ser entendidas.
O que o build faz
Vale começar por aqui, porque tudo decorre disso.
Durante o desenvolvimento, existe um servidor que compila o código sob demanda, recarrega a página a cada alteração e mantém informações extras para facilitar a depuração.
O build de produção é outra coisa. Ele:
- Converte o código para uma forma que os navegadores entendem.
- Une e reduz os arquivos, removendo espaços, encurtando nomes internos e eliminando código não utilizado.
- Divide o resultado em partes, permitindo carregar sob demanda o que não é necessário na primeira tela.
- Adiciona um identificador ao nome de cada arquivo gerado, derivado do seu conteúdo.
- Substitui as variáveis de ambiente pelos valores fixos, embutindo-os no código.
- Remove ferramentas e informações de desenvolvimento.
Os passos 4 e 5 são a origem da maior parte dos problemas de produção, e cada um merece uma seção.
Variáveis de ambiente: elas ficam públicas
Este é o ponto mais importante do artigo, e a fonte de vazamentos reais.
Em uma aplicação de servidor, variáveis de ambiente são lidas em tempo de execução e ficam no servidor. Em uma aplicação que roda no navegador, isso é impossível: o código precisa ser entregue pronto ao visitante, então qualquer valor usado por ele é embutido no arquivo durante o build.
A consequência é direta e não tem contorno: qualquer pessoa pode ler essas variáveis abrindo os arquivos da aplicação no navegador. Não é uma questão de esconder melhor — o valor está literalmente no arquivo baixado.
A regra que evita incidentes: no código do navegador só entram valores que você aceitaria publicar. Endereço da API, identificador público de um serviço, chave de configuração de mapa com restrição de domínio. Nunca uma credencial de banco, uma chave com permissão de escrita ou um segredo de integração.
Se a aplicação precisa de uma operação que exige credencial sensível, essa operação vai para um serviço de back-end que o navegador apenas chama — o que nos leva ao ponto seguinte.
A consequência que surpreende
Como as variáveis são embutidas no build, elas não podem ser trocadas depois. Se você gerou o pacote apontando para o ambiente de homologação, publicá-lo em produção não vai corrigir o endereço: é preciso gerar um novo build.
Isso significa que cada ambiente exige seu próprio build, e que promover “o mesmo pacote” de homologação para produção não funciona da forma como funcionaria em uma aplicação de servidor. É uma diferença de fluxo que costuma pegar equipes acostumadas ao outro modelo.
Cache: por que o usuário continua vendo a versão antiga
O segundo problema clássico, e a solução está no passo 4 do build.
Ferramentas de build adicionam ao nome de cada arquivo gerado um identificador derivado do conteúdo. Se o conteúdo muda, o nome muda. Isso permite uma política de cache em duas velocidades:
| Arquivo | Política de cache | Por quê |
|---|---|---|
| Arquivos com identificador no nome | Cache longo | O nome muda quando o conteúdo muda |
| HTML principal | Cache curto ou nenhum | O nome é sempre o mesmo |
| Manifesto e ícones | Cache curto | Referenciados por nome fixo |
A lógica: o HTML principal é o índice que aponta para os demais arquivos. Se ele estiver cacheado por muito tempo, o navegador continuará pedindo os arquivos antigos — mesmo que os novos já estejam no servidor.
É por isso que “o usuário está vendo a versão antiga” quase sempre significa HTML principal com cache longo demais. E o sintoma pode ser pior que apenas conteúdo desatualizado: se os arquivos antigos já foram removidos do servidor, o navegador pede algo que não existe mais e a aplicação simplesmente não carrega.
Vale conferir essa política em todas as camadas — servidor, proxy e, principalmente, CDN, que é a mais esquecida, como tratamos no artigo sobre o que é CDN.
O processo de publicação
Um roteiro que evita os problemas descritos:
- Instale as dependências de forma reprodutível, respeitando o arquivo de bloqueio, para que a máquina de build use exatamente as versões testadas.
- Defina as variáveis do ambiente de destino antes de gerar o build.
- Gere o build, e verifique se ele terminou sem erros — falhas silenciosas em etapas de build são comuns.
- Publique os arquivos novos antes de remover os antigos, para que navegadores com o HTML anterior ainda encontrem o que pedem.
- Aplique a política de cache conforme a tabela acima.
- Verifique carregando a aplicação em uma janela limpa e conferindo se a versão publicada é a esperada.
- Mantenha a versão anterior disponível por alguns dias, como caminho de volta.
O passo 4 merece destaque porque é contraintuitivo: durante alguns minutos após a publicação, existem navegadores com o HTML antigo em memória, pedindo arquivos da versão anterior. Removê-los imediatamente quebra a experiência dessas pessoas.
E o passo 7 é o que separa um problema de minutos de uma tarde perdida. Voltar uma versão em uma aplicação de arquivos estáticos é simples — desde que os arquivos anteriores ainda existam.
Ambientes separados
Como cada ambiente exige seu próprio build, a separação precisa existir desde o começo:
- Desenvolvimento, na máquina de quem programa, apontando para uma API local ou de teste.
- Homologação, com build próprio apontando para os serviços de teste, para validar o comportamento real do pacote de produção.
- Produção, com build próprio e variáveis definitivas.
Um erro que aparece com frequência: testar apenas no ambiente de desenvolvimento e publicar direto. Como o build de produção remove ferramentas de depuração e otimiza o código, existem comportamentos que só aparecem nele — e descobrir isso em produção é caro.
A recomendação prática é simples: gere o build de produção e teste-o localmente antes de publicar. Leva minutos e revela boa parte dos problemas.
Peso do pacote: o custo que o visitante paga
Uma aplicação React entrega ao navegador todo o código necessário para funcionar. Esse pacote é baixado, interpretado e executado pelo dispositivo do visitante — e em conexões e aparelhos modestos, isso pesa.
O que mais faz diferença:
- Dividir o código por rota, carregando apenas o necessário para a tela inicial.
- Revisar dependências pesadas. Uma biblioteca completa importada para usar uma função é um custo desproporcional.
- Carregar sob demanda o que não é essencial de imediato.
- Verificar o conteúdo do pacote com as ferramentas de análise disponíveis, que mostram o que está ocupando espaço.
A última prática costuma ser reveladora: é comum descobrir que uma parte significativa do pacote vem de uma dependência que ninguém lembrava ter adicionado.
Erros comuns depois da publicação
| Sintoma | Causa provável |
|---|---|
| Aplicação carrega em branco | Erro em tempo de execução ou arquivo faltando |
| Versão antiga persiste | HTML principal com cache longo |
| Erro ao carregar arquivo inexistente | Arquivos antigos removidos cedo demais |
| Chamadas indo para o endereço errado | Build gerado com variáveis do ambiente errado |
| Rota interna dá erro ao recarregar | Falta regra de reescrita no servidor |
| Funciona em desenvolvimento e não em produção | Comportamento alterado pelo build otimizado |
A penúltima linha é o problema número um de quem publica React pela primeira vez, e está tratada no artigo sobre onde hospedar uma aplicação React, junto com as arquiteturas possíveis.
Conclusão
O build de produção não é apenas uma versão comprimida do que roda em desenvolvimento — é um processo que embute valores, renomeia arquivos e altera comportamentos. Entender isso resolve a maior parte dos problemas que aparecem só depois da publicação.
Duas regras concentram o essencial: no código do navegador só entram valores que você aceitaria publicar, porque eles ficam legíveis para qualquer pessoa; e o HTML principal precisa de cache curto, porque é ele que aponta para todo o resto.
E uma prática que economiza tempo: gerar o build de produção e testá-lo antes de publicar. Se a sua aplicação também inclui uma API própria, o ambiente precisa executar serviços permanentes — conheça o Cloud Server para React da TBF Host e avalie a configuração adequada ao projeto.
Perguntas frequentes
As variáveis de ambiente de uma aplicação React são seguras?
Não, quando usadas no código que roda no navegador. Elas são embutidas nos arquivos durante o build e podem ser lidas por qualquer pessoa que abra a aplicação. A regra é simples: ali só entram valores que você aceitaria publicar. Credenciais e chaves com permissão de escrita precisam ficar em um serviço de back-end.
Posso trocar as variáveis de ambiente depois do build?
Não. Elas são substituídas por valores fixos durante o processo, então o pacote gerado carrega os valores do ambiente para o qual foi construído. Isso significa que cada ambiente exige seu próprio build, e que promover o mesmo pacote de homologação para produção não corrige os endereços.
Por que os usuários continuam vendo a versão antiga do site?
Quase sempre porque o HTML principal está com cache longo demais. Ele é o índice que aponta para os demais arquivos e tem nome fixo, então precisa de cache curto ou nenhum. Os arquivos com identificador no nome podem ter cache longo, porque o nome muda sempre que o conteúdo muda.
Por que aparece erro de arquivo não encontrado depois de publicar?
Provavelmente porque os arquivos da versão anterior foram removidos cedo demais. Durante alguns minutos após a publicação, existem navegadores com o HTML antigo em memória pedindo arquivos daquela versão. Publicar os novos antes de remover os antigos evita esse problema.
Qual a política de cache correta para uma aplicação React?
Cache longo para os arquivos que têm identificador no nome, já que ele muda quando o conteúdo muda; cache curto ou nenhum para o HTML principal e para arquivos referenciados por nome fixo, como manifesto e ícones. Vale conferir essa política no servidor, no proxy e na CDN.
Por que a aplicação funciona em desenvolvimento e falha em produção?
Porque o build de produção remove ferramentas de depuração, otimiza o código e altera comportamentos. Existem problemas que só aparecem nesse contexto. A prática que evita isso é gerar o build de produção e testá-lo localmente antes de publicar — leva minutos e revela boa parte dos casos.
Como reduzir o tamanho do pacote de uma aplicação React?
Dividindo o código por rota para carregar apenas o necessário na tela inicial, revisando dependências pesadas, carregando sob demanda o que não é essencial de imediato e analisando o conteúdo do pacote com as ferramentas disponíveis, que costumam revelar dependências esquecidas ocupando espaço.
Como voltar para a versão anterior depois de uma publicação problemática?
Mantendo os arquivos da versão anterior disponíveis por alguns dias. Em uma aplicação de arquivos estáticos, voltar é simples — desde que eles ainda existam. É o item que mais economiza tempo em um incidente e o mais fácil de cortar por descuido no processo de publicação.