Capítulo 27 de 456

Building

Core Idea

next build compila, prerenderiza o que pode e imprime uma tabela de rotas com símbolos que mostram como cada URL é servida. Com Cache Components, erros de "prerender-blocking" são a forma do build pegar dados não cacheados/runtime antes que virem lentidão em produção.

Key Concepts

  • Fases do build: Setup (env vars, config, build ID) → Route discovery (app/, pages/, proxy, instrumentation) → Compilation (Turbopack/webpack, type check em paralelo) → Static analysis (classifica cada rota, roda generateStaticParams, checa erros de prerender) → Prerendering (HTML + RSC payloads) → Output (.next/, standalone, export).
  • Símbolos da tabela de rotas: Static (build time), Partial Prerender (shell estático + streaming), SSG (generateStaticParams/getStaticProps), ƒ Dynamic (server-rendered por request, sem nada pra prerenderizar).
  • --debug-prerender: desliga minificação, ativa source maps no servidor, continua após a primeira falha (mostra todos os erros de uma vez). Nunca fazer deploy de build gerado com essa flag.
  • --debug-build-paths: builda/prerenderiza só as rotas indicadas (glob, ! pra excluir), útil pra iterar numa rota específica de app grande.
  • Colunas Revalidate/Expire: aparecem quando a rota contém cache; reportam o menor revalidate/maior expire entre todos os caches da rota (mesmo sem cacheLife explícito, usa o profile default).

Code Examples

next build --debug-prerender
  • O que demonstra: gera stack trace apontando a linha exata do acesso bloqueante (ex. await props.params), essencial quando o erro de produção só mostra código minificado.
// fix [stream]: loading.tsx cria boundary de Suspense automático
export default function Loading() {
  return <div>Loading...</div>
}
  • O que demonstra: transforma a rota de erro de build em Partial Prerender: shell prerenderiza, conteúdo real streama.
// fix [cache]: cachear a busca de dado torna o param prerenderizável em full (○)
async function getProduct(id: string) {
  'use cache'
  const res = await fetch(`https://api.example.com/products/${id}`)
  return res.json()
}
  • O que demonstra: combinado com generateStaticParams, params listados viram completo; params não listados ficam (shell + stream).
// fix [block]: opt-out de validação, mantém bloqueio deliberado
export const instant = false
  • O que demonstra: sem fallback de UI, usuário não vê nada até a busca terminar; usar só quando bloquear é intencional.

Reference Tables

SímboloNomeComportamento
StaticTotalmente prerenderizado em build time
Partial PrerenderShell estático imediato, conteúdo dinâmico streama
SSGHTML estático via generateStaticParams/getStaticProps
ƒDynamicRenderizado por request (sem nada prerenderizável)
Sugestão do erroAção
[stream]Envolver com <Suspense fallback> (ex. loading.tsx)
[cache]Adicionar 'use cache' na busca
[block]export const instant = false (opt-out deliberado)

Anti-patterns

  • Deploy de build com --debug-prerender: pula otimizações de produção.
  • generateStaticParams retornando array vazio: causa build error.
  • Assumir que ƒ Dynamic ainda é o padrão: com Cache Components, Partial Prerendering é o modelo default; ƒ só aparece quando não há nada pra prerenderizar (Route Handlers dependentes de request, proxy, metadata dinâmica).
  • Ignorar Math.random()/new Date() em rota prerenderizada: falha o build por serem valores não determinísticos.

Key Takeaways

  1. A tabela de rotas pós-build é a fonte de verdade sobre como cada URL é de fato servida, não os configs de validação exportados.
  2. Erros de prerender-blocking (blocking-prerender-runtime/blocking-prerender-dynamic) têm três saídas: stream, cache, ou block deliberado.
  3. next dev mostra o erro completo com componente/linha resolvidos, mais rápido pra debugar que produção.
  4. --debug-build-paths acelera iteração em apps grandes sem rebuildar tudo.
  5. Rotas com cookies()/headers()/searchParams permanecem mesmo com cache, porque essas partes sempre streamam por request.

Connects To

  • Caching (getting-started): conceitos de use cache, cacheLife, static shell que todo este capítulo pressupõe.
  • Instant Navigation: instant = false e o fluxo de migração completo.
  • ISR with Cache Components: o que acontece quando um param não listado é visitado (upgrade em background).
  • CI Build Caching: como persistir .next/cache entre builds em CI.