Pular para o conteúdo
Navegar na documentação

Pipeline e serviços de build

BuildCommand cria BuildPipeline::default() e apenas formata o progresso. O pipeline recebe uma lista ordenada de objetos BuildStage, cria um BuildContext, executa cada estágio uma vez e acumula BuildStageResult em BuildReport.

O contexto transporta o nome do CSS gerado, os caminhos dos WOFF2 publicados para preload, o manifesto de assets de CompileAssetsStage/estágios de resolução para RenderPagesStage e o cache incremental opcional. Se um estágio lança exceção, não há captura no pipeline, relatório final ou execução dos estágios restantes.

Estágios padrão e delegados:

Estágio Serviço
ValidateDependenciesStage BuildService::validateTailwindDependency(), PagefindService, MermaidRenderer e ShikiRenderer quando habilitados
CleanDistStage BuildService::cleanDist()
CompileAssetsStage BuildService::compileAssets()
ResolveRevealJsStage RevealJsService
ResolveRemixIconStage RemixIconService
CopyFaviconAssetsStage BuildService::copyFaviconAssets()
RenderPagesStage BuildService::renderPages()
ResolvePagefindStage PagefindService
GenerateMdxSourcesStage MdxSourceService
GenerateFeedsStage FeedService
GenerateSitemapStage SitemapService
GenerateRobotsStage RobotsService
GenerateLlmsTxtStage LlmsTxtService
ValidateInternalLinksStage InternalLinkValidator
GenerateCoversStage CoverService
PrecompressOutputStage CompressionService

BuildWarnings é um acumulador estático drenado pelos estágios de páginas e sitemap. Os serviços devolvem DTOs de resultado com itens gerados e tempo; os estágios os transformam em linhas e warnings de console.

RenderPagesStage grava rotas normais em <rota>/index.html, a home em index.html e todas as rotas marcadas como páginas de erro em arquivos planos <código>.html. /404 continua sendo obrigatório porque o router estático o usa como fallback para caminhos desconhecidos; os demais códigos são publicados quando suas fontes existem em Content/Pages/_errors/<código>/.

ResolveRemixIconStage roda depois de CompileAssetsStage. Quando habilitado, o RemixIconService prepara o CSS e as fontes em memória, registra todas as saídas no OutputRegistry e troca o namespace dist/assets/remixicon/ atomicamente. O manifest recebe css/remixicon.css, mantendo os layouts independentes dos hashes. No modo dev, Application só anuncia essa entrada quando a configuração está habilitada e o CSS está presente.

ResolvePagefindStage roda imediatamente depois de RenderPagesStage, pois precisa dos HTML finais. Quando habilitado, PagefindService executa o binário local sobre dist/, grava o índice em diretório temporário e troca dist/pagefind/ atomicamente. O namespace é reservado no OutputRegistry para impedir colisões com Content/public; sem o recurso, uma publicação antiga é removida.

ValidateInternalLinksStage roda depois de todos os documentos auxiliares e antes das capas. InternalLinkValidator percorre cada HTML em dist/, resolve hrefs relativos e URLs HTTP(S) do mesmo domínio contra os arquivos publicados e verifica fragmentos somente quando o destino é HTML, usando id e a[name]. Isso permite links para saídas como feeds XML e fontes MDX. Links externos e esquemas não navegáveis ficam fora do escopo. Ao encontrar falhas, acumula os pares origem/destino e interrompe o build antes de publicar compressões ou capas.

ResolveRevealJsStage roda entre CompileAssetsStage e ResolveRemixIconStage no pipeline padrão. RevealJsService respeita feature.revealjs e publica reveal.mjs e reveal.css no namespace dist/assets/reveal/, com hashes no build e nomes estáveis em public/assets/reveal/ no modo dev. O manifest expõe essas saídas como js/reveal.js e css/reveal.css. Páginas MDX com type: presentation geram a rota de artigo e uma segunda rota <rota>/slides.html; a segunda usa o layout Reveal.js e é noindex com canonical apontando para o artigo. O RouteCatalog resolve essa variante no servidor dinâmico sem adicioná-la às rotas indexáveis.

Quando feature.mermaid está habilitado, ValidateDependenciesStage valida o CLI Mermaid e o Chromium. Durante a descoberta MDX, o renderer customizado de fences executa o mmdc e embute o SVG produzido no HTML do artigo e dos slides; não há runtime Mermaid. Se Content/assets/css/mermaid.css existir, ele é compilado como entrada CSS do usuário e registrado no manifest para ser carregado pelos layouts.

Quando feature.shiki está habilitado, ValidateDependenciesStage valida Node.js e o pacote local shiki. O ShikiRenderer mantém um worker Node por build e encaminha a ele os fences de linguagens conhecidas; assim temas e gramáticas são carregados uma vez e reutilizados por artigos e apresentações. O worker devolve HTML com estilos inline e só existe durante o build: não há asset, JavaScript ou runtime Shiki em dist/. Fences sem linguagem ou sem gramática conhecida seguem o renderer CommonMark padrão.

Para um contrato passo a passo destinado a implementar a mesma arquitetura em outro projeto, consulte Criar e personalizar apresentações.

Os serviços que dependem de conteúdo recebem a mesma instância de RouteCatalog. O catálogo é lazy e vive somente durante o comando ou request, evitando repetir parsing e consultas Git sem manter dados obsoletos entre execuções. Seu resultado inclui as rotas e, somente para Collections opt-in, os documentos necessários a llms_full, feeds ou à publicação das fontes MDX. MdxSourceService grava os arquivos originais depois de renderizar as páginas e antes dos índices. GitFileDates resolve criação e modificação com um único histórico por arquivo e não abre processos Git quando nenhum repositório está montado.

ValidateDependenciesStage é sempre o primeiro estágio e verifica se node_modules/.bin/tailwindcss existe e é executável. Quando habilitados, Pagefind e Mermaid também são validados; Mermaid exige ainda um Chromium executável. A mensagem do Tailwind inclui o pacote/versão esperados (@tailwindcss/cli ^4.0.0) e orienta npm ci ou npm install; todas as validações ocorrem antes de limpar dist/.

GenerateCoversStage pode ser removido da composição por --fast. No fluxo completo, CoverService inicia um php -S temporário sobre dist/, repassa ao renderer o manifesto de assets e o contexto de fontes (fontStylesheet e fontPreloads) usado pelas páginas, e mantém até --cover-jobs processos Chromium Headless ativos. O router estático aplica site.basePath exatamente como a publicação final e libera CORS para que o documento file:// carregue CSS, fontes e outros assets publicados. Cada resultado é comprimido com optipng -o2 -strip all; o servidor é encerrado mesmo quando uma cover falha. Com o cache incremental habilitado, a assinatura do HTML renderizado permite copiar covers inalteradas sem executar o Chromium.

PrecompressOutputStage percorre as saídas textuais e cria os sidecars .br e .gz. O CompressionService identifica cada entrada pelo hash do conteúdo e reutiliza os dois sidecars de storage/framework/build-cache/v1/ quando disponíveis. O relatório do estágio informa hits e misses; --no-cache força as compressões novamente sem ler ou escrever artefatos incrementais.

ServeService fica fora do pipeline. Ele resolve host/porta, gerencia o processo Tailwind e inicia o servidor PHP dinâmico ou estático. Generators também são separados: PageGenerator e ComponentGenerator escrevem templates em Content/ e seus Commands convertem exceções esperadas em código de falha.