Pular para o conteúdo
Development

Compartilhando um blog Astro entre dois sites

Por Victor Da Luz
astronpmcidev-logastro-tools

Eu queria um dev log no imperfectsystems.com. O blog que já tenho no vdaluz.com funciona bem, então o movimento óbvio era reaproveitar o código dele em vez de escrever um segundo do zero. “Reaproveitar” acabou sendo mais interessante do que eu esperava.

Você não consegue extrair um blog

Meu primeiro instinto foi “extrair o blog para um pacote”. Isso não é uma coisa real em Astro. Rotas moram em src/pages/ e precisam ficar em cada app. Conteúdo é uma pasta de markdown por site. A configuração do Shiki, a configuração do Tailwind e o CSS de tema também são todos por app. O que é de fato portável é menor do que parece: os componentes que renderizam um card de post, uma barra de paginação, a lista de posts relacionados, mais a função de pontuação e o schema de conteúdo.

Então a versão honesta do objetivo não é “blog compartilhado”. É “uma pequena biblioteca de componentes, mais um pouco de cola em cada site”. Assim que enquadrei dessa forma, o design ficou fácil.

Um pacote, duas paletas

vdaluz.com é um site claro/escuro com um destaque azul. imperfectsystems é preto com verde neon. Se os componentes compartilhados tivessem qualquer cor fixa no código, isso desmorona. Eles não têm. Cada componente referencia tokens de design em variáveis CSS como bg, surface, accent. O pacote nunca diz o que eles significam. Cada site define os valores no seu próprio CSS.

Esse é todo o truque. O mesmo PostCard renderiza azul-sobre-branco num site e verde-sobre-preto no outro, sem nenhum fork. Eu também tirei a dependência do tipo CollectionEntry<'blog'> do Astro, trocando por um tipo estrutural simples, então o pacote não se importa com o nome que cada site dá para sua coleção.

Duas formas como o CI me mordeu

O pacote builda localmente na primeira tentativa. Aí eu fiz push, e o CI falhou duas vezes por motivos que nunca aparecem no meu notebook.

Primeiro: uma dependência github:user/repo é reescrita pelo npm para uma URL git+ssh no lockfile. Até uma URL git+https explícita é reescrita. Minha máquina tem uma chave SSH, então clona sem problema. O runner do CI não tem, então o npm ci não conseguia buscar o pacote de jeito nenhum. O ajuste para um repositório público é pular o git por completo e depender de um tarball fixado: https://github.com/vdaluz/astro-blog/archive/refs/tags/v0.1.0.tar.gz. Https simples, anônimo, com um hash de integridade.

Segundo, e mais chato: eu regenerei o lockfile no meu Mac para resolver um conflito de merge. Isso silenciosamente escreveu só o build macOS do rollup no lockfile e descartou o Linux. No runner Linux do CI, o build morreu com Cannot find module @rollup/rollup-linux-x64-gnu. Isso é um bug conhecido do npm com dependências nativas opcionais. O ajuste foi restaurar o lockfile que estava correto e adicionar minha única dependência nova com npm install --package-lock-only, o que mantém os binários de toda plataforma em vez de reduzir para a minha.

A lição que continuo reaprendendo: um build verde na minha máquina não diz nada sobre um runner Linux sem chave SSH. Agora eu rodo npm ci && npm run build no node 22 antes de confiar num push.

Onde isso chegou

imperfectsystems.com/blog está no ar, renderizando pelo pacote compartilhado em pleno neon. vdaluz.com ainda tem sua própria cópia por enquanto, movê-lo para o pacote é o próximo passo. Dois sites, um conjunto de componentes, e algumas cicatrizes de CI para mostrar no caminho.

Leitura relacionada

Você também pode achar útil

Proton

Proton Pass

Gerenciador de senhas focado em privacidade, da equipe por trás do Proton Mail.

Como parceiro da Proton, ganho com compras qualificadas dos serviços de privacidade e segurança da Proton (Pass, Mail, VPN, Drive).

Saiba mais
Proton

Proton Mail

E-mail criptografado de ponta a ponta, com arquitetura de acesso zero.

Como parceiro da Proton, ganho com compras qualificadas dos serviços de privacidade e segurança da Proton (Pass, Mail, VPN, Drive).

Saiba mais
AdGuard

AdGuard para iOS

Bloqueio de anúncios e rastreadores em todo o sistema no iOS, sem necessidade de um servidor DNS separado.

Como afiliado da AdGuard, ganho com compras qualificadas.

Saiba mais