core/landing
Tiago Yamamoto 92509d5155 docs: corrige configuração do Deno Deploy
- Atualiza landing/README.md com configuração correta do Deno Deploy
- Adiciona DENO_DEPLOY_FIX.md com troubleshooting detalhado
- Explica que 'deno install' não existe e deve ser removido
- Documenta valores corretos: Install command (vazio), Build Directory (landing)
- Adiciona tabela comparativa Deno vs npm/yarn
- Inclui workflow GitHub Actions opcional para CI/CD
- Corrige erro: 'Executing install command - build failed'
2025-12-11 20:09:24 -03:00
..
.vscode Replace binary favicon with SVG asset 2025-12-11 18:12:14 -03:00
components Replace binary favicon with SVG asset 2025-12-11 18:12:14 -03:00
islands Replace binary favicon with SVG asset 2025-12-11 18:12:14 -03:00
routes Replace binary favicon with SVG asset 2025-12-11 18:12:14 -03:00
static Fix Deno deploy dependency resolution 2025-12-11 19:12:59 -03:00
.gitignore Replace binary favicon with SVG asset 2025-12-11 18:12:14 -03:00
.gitkeep Add monorepo scaffold and Appwrite cloud configuration 2025-12-11 18:01:19 -03:00
deno.json Configure Deno tasks for system CA store 2025-12-11 19:20:37 -03:00
DENO_DEPLOY_FIX.md docs: corrige configuração do Deno Deploy 2025-12-11 20:09:24 -03:00
dev.ts Replace binary favicon with SVG asset 2025-12-11 18:12:14 -03:00
fresh.config.ts Replace binary favicon with SVG asset 2025-12-11 18:12:14 -03:00
fresh.gen.ts Replace binary favicon with SVG asset 2025-12-11 18:12:14 -03:00
main.ts Replace binary favicon with SVG asset 2025-12-11 18:12:14 -03:00
README.md docs: corrige configuração do Deno Deploy 2025-12-11 20:09:24 -03:00
tailwind.config.ts Replace binary favicon with SVG asset 2025-12-11 18:12:14 -03:00

Landing Page - Core Platform

Landing page desenvolvida com Fresh (framework Deno) e Tailwind CSS. Server-side rendering para performance máxima.

🎯 Visão Geral

Landing page pública da plataforma DevOps, com:

  • Server-Side Rendering (SSR) nativo
  • Componentes interativos (Islands Architecture)
  • Páginas estáticas otimizadas
  • Tailwind CSS integrado

🛠 Stack Tecnológica

📦 Instalação

Pré-requisito: Deno

# Linux/Mac
curl -fsSL https://deno.land/install.sh | sh

# Windows (PowerShell)
irm https://deno.land/install.ps1 | iex

# Verificar instalação
deno --version

Dependências

Fresh gerencia dependências automaticamente via deno.json. Não precisa npm install!

As dependências são baixadas na primeira execução:

cd landing
deno task start

🏃 Scripts

Todos os scripts estão definidos em deno.json:

Comando Descrição
deno task start Inicia dev server (porta 8000) com hot reload
deno task build Gera build de produção
deno task preview Serve build de produção
deno task check Executa fmt + lint + type-check
deno task manifest Regenera arquivo de rotas

Executar em Desenvolvimento

deno task start

Acesse: http://localhost:8000

Hot Reload: Alterações em routes/ e islands/ recarregam automaticamente.

📁 Estrutura de Pastas

landing/
├── routes/              # 🗺️ Rotas (SSR)
│   ├── index.tsx        # Homepage (/)
│   ├── _app.tsx         # Layout global
│   ├── _404.tsx         # Página 404
│   ├── greet/
│   │   └── [name].tsx   # Rota dinâmica (/greet/:name)
│   └── api/
│       └── joke.ts      # API endpoint (/api/joke)
│
├── islands/             # 🏝️ Componentes interativos (client-side)
│   ├── Counter.tsx      # Exemplo de contador
│   └── ServerStatus.tsx # Widget de status
│
├── components/          # 🧩 Componentes estáticos (SSR only)
│   ├── Button.tsx
│   └── Header.tsx
│
├── static/              # 📦 Arquivos estáticos
│   ├── logo.svg
│   ├── favicon.ico
│   └── styles.css
│
├── deno.json            # Configuração Deno + tarefas
├── fresh.config.ts      # Configuração Fresh
├── fresh.gen.ts         # Auto-gerado (manifesto de rotas)
├── main.ts              # Entry point produção
├── dev.ts               # Entry point desenvolvimento
└── tailwind.config.ts   # Configuração Tailwind

🏗️ Arquitetura Fresh

Routes (SSR)

Arquivos em routes/ são renderizados no servidor:

// routes/index.tsx
export default function Home() {
  return (
    <div>
      <h1>Homepage</h1>
      <p>Renderizado no servidor!</p>
    </div>
  );
}

Rotas dinâmicas:

// routes/greet/[name].tsx
export default function GreetPage(props) {
  const { name } = props.params;
  return <h1>Olá, {name}!</h1>;
}

Islands (Client-Side)

Componentes em islands/ são hidratados no cliente:

// islands/Counter.tsx
import { Signal, signal } from "@preact/signals";

export default function Counter() {
  const count = signal(0);
  
  return (
    <div>
      <p>Contador: {count}</p>
      <button onClick={() => count.value++}>+1</button>
    </div>
  );
}

Quando usar Islands:

  • Formulários interativos
  • Widgets dinâmicos
  • Animações client-side

Quando usar Routes:

  • Conteúdo estático
  • SEO crítico
  • Performance máxima

API Routes

// routes/api/joke.ts
export const handler = {
  GET() {
    const joke = "Por que o JavaScript foi ao psicólogo? Porque tinha muitos callbacks!";
    return new Response(JSON.stringify({ joke }), {
      headers: { "Content-Type": "application/json" },
    });
  },
};

Acesse: http://localhost:8000/api/joke

🎨 Tailwind CSS

Fresh integra Tailwind via plugin:

// Usar classes normalmente
<div class="bg-blue-500 text-white p-4 rounded-lg">
  Card estilizado
</div>

Configuração: tailwind.config.ts

🧪 Testes

Type Checking

deno task check

Executa:

  1. deno fmt --check (formatação)
  2. deno lint (linting)
  3. deno check **/*.ts (type-check)

Corrigir Formatação

deno fmt

🚀 Deploy

Deno Deploy (Recomendado)

⚠️ IMPORTANTE - Configuração Correta:

No painel do Deno Deploy, configure:

Campo Valor Correto Valor Incorreto
Build Directory landing \landing
Install command (deixe vazio) deno install
Build command deno task build
Entrypoint main.ts

Por que deixar Install command vazio?

O Deno não precisa de comando install! Ele baixa dependências automaticamente via deno.json (import maps). O comando deno install não existe e causa erro:

❌ Executing install command
   deno install
   Error: Command not found

Configuração Detalhada:

  1. Via GitHub (automático):

    1. Push para GitHub
    2. Conecte repo em https://dash.deno.com
    3. Configure:
       - Framework: Fresh
       - Build Directory: landing
       - Install command: (DEIXE VAZIO!)
       - Build command: deno task build
       - Root Directory: / (se o repo inteiro)
    4. Deploy feito em cada push
    
  2. Via CLI:

    # Instalar CLI
    deno install -Arf --global https://deno.land/x/deploy/deployctl.ts
    
    # Deploy direto
    cd landing
    deployctl deploy --project=seu-projeto main.ts
    

Arquivo de configuração (opcional):

Crie landing/.github/workflows/deploy.yml:

name: Deploy to Deno Deploy

on:
  push:
    branches: [main]
    paths:
      - 'landing/**'

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    
    steps:
      - name: Clone repository
        uses: actions/checkout@v4
      
      - name: Setup Deno
        uses: denoland/setup-deno@v1
        with:
          deno-version: v1.x
      
      - name: Build
        run: |
          cd landing
          deno task build          
      
      - name: Deploy to Deno Deploy
        uses: denoland/deployctl@v1
        with:
          project: seu-projeto
          entrypoint: landing/main.ts
          root: landing

Docker (Self-Hosted)

FROM denoland/deno:alpine

WORKDIR /app
COPY . .
RUN deno cache dev.ts

EXPOSE 8000
CMD ["deno", "task", "start"]
docker build -t core-landing .
docker run -p 8000:8000 core-landing

Fly.io

flyctl launch
flyctl deploy

⚙️ Configuração Avançada

Variáveis de Ambiente

Fresh carrega .env automaticamente (se existir):

# landing/.env
API_URL=https://api.example.com

Acesso:

const apiUrl = Deno.env.get("API_URL");

⚠️ Segurança: Não exponha secrets no client! Use apenas em API routes.

Custom Middleware

// routes/_middleware.ts
export async function handler(req, ctx) {
  console.log("Request:", req.url);
  const resp = await ctx.next();
  resp.headers.set("X-Custom-Header", "Fresh");
  return resp;
}

DENO_TLS_CA_STORE=system

Se sua rede usa certificados customizados:

# deno.json já inclui por padrão
DENO_TLS_CA_STORE=system deno task start

🔧 Troubleshooting

"Import map not found"

Solução: Regenerar manifesto

deno task manifest

Erro ao baixar dependências

Solução: Limpar cache

deno cache --reload dev.ts

Port 8000 já em uso

Solução: Alterar porta em dev.ts

await start(manifest, { port: 3000 });

Tailwind não funciona

Solução: Verificar plugin em fresh.config.ts

import twindPlugin from "$fresh/plugins/twind.ts";

export default {
  plugins: [twindPlugin(twindConfig)],
};

📚 Recursos

🆚 Fresh vs Outros Frameworks

Feature Fresh Next.js SvelteKit
Runtime Deno Node.js Node.js
SSR Nativo
Islands Automático
Bundle size 0 KB default ~70 KB ~20 KB
TypeScript Nativo Precisa config Precisa config
Deploy Deno Deploy Vercel Vercel/Netlify

Vantagens Fresh:

  • Zero JavaScript no cliente por padrão
  • TypeScript sem configuração
  • Deploy instantâneo (Deno Deploy)
  • Deno = segurança e performance

Para configuração completa do monorepo, veja o README principal.