Poorgramer-Zack/dart-expert-skills

Uma biblioteca abrangente de Skills de Agente modulares para desenvolvimento Flutter & Dart

O que é dart-expert-skills?

Este skill fornece um guia completo e prático para desenvolvedores que desejam construir aplicações web modernas com o framework Jaspr (v0.22.x) em Dart. Diferente do Flutter Web, que renderiza pixels via Canvas e prejudica o SEO, o Jaspr compila Dart para elementos HTML e CSS semânticos. O skill cobre desde os conceitos fundamentais, como a criação de componentes que imitam o modelo do Flutter (StatelessComponent, StatefulComponent, InheritedComponent), até integrações avançadas com Tailwind CSS, roteamento declarativo com jaspr_router e, principalmente, renderização no servidor (SSR) para carregamento assíncrono de dados. É ideal para sites, blogs, landing pages ou qualquer projeto que exija SEO adequado e performance inicial superior. O conteúdo inclui exemplos de código detalhados, tabelas de mapeamento de conceitos entre Flutter e Jaspr, e instruções claras sobre os três tipos de teste disponíveis: virtual (testComponents), servidor (testServer) e navegador (testClient), garantindo que o desenvolvedor possa validar cada camada da aplicação de forma eficiente.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add Poorgramer-Zack/dart-expert-skills

Installed? Explore more Programação e Desenvolvimento skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Guia de Arquitetura Web Jaspr (v0.22.x)

Objetivo

Jaspr é um framework web Dart (versão atual: 0.22.x).

Ao contrário do Flutter Web (que desenha pixels via Canvas e produz SEO ruim), o Jaspr compila Dart para elementos HTML e CSS semânticos. Use Jaspr para sites, blogs, landing pages ou qualquer projeto que exija SEO adequado.

Instruções

1. Conceito Central: Experiência de Codificação Similar ao Flutter

O Jaspr espelha o modelo de componentes do Flutter. O método build retorna um único Component (equivalente a um Widget do Flutter).

Conceito FlutterConceito JasprNotas
WidgetComponentTodo elemento de UI no Jaspr é um Component
StatelessWidgetStatelessComponentUI declarativa pura; recebe BuildContext context
StatefulWidgetStatefulComponentGerencia ciclo de vida com setState, initState, createState()
InheritedWidgetInheritedComponentPropaga estado para baixo na árvore de componentes

1.1 Elementos DOM

O Jaspr renderiza para o DOM, portanto use seus helpers de tags HTML (div, p, img, etc.) de jaspr/dom.dart.

import 'package:jaspr/jaspr.dart';

class ProfileCard extends StatelessComponent {
  final String name;

  const ProfileCard({required this.name, super.key});

  @override
  Component build(BuildContext context) {
    return div(
      classes: 'profile-card',
      styles: Styles.box(width: 300.px, backgroundColor: Colors.white),
      [
        h2([.text(name)]), // 🌟 .text() shorthand disponível desde Dart 3.10 (Component.text)
        p([
          .text('Hello World!'),
        ]),
        button(
          onClick: () => print('Button successfully clicked!'),
          [.text('Contact Me')]
        )
      ]
    );
  }
}

2. Integração com Tailwind CSS (jaspr_tailwind)

O Jaspr fornece integração oficial com Tailwind CSS via jaspr_tailwind.

2.1 Instalação e Configuração

dev_dependencies:
  jaspr_tailwind: ^0.1.0

Crie web/styles.tw.css com a sintaxe CSS-first do Tailwind v4:

/* web/styles.tw.css */
@import "tailwindcss";

2.2 Carregando CSS Compilado no Componente Raiz

No componente raiz, use Document para vincular a folha de estilo compilada e consuma as classes Tailwind através do parâmetro classes:

import 'package:jaspr/jaspr.dart';

class App extends StatelessComponent {
  @override
  Component build(BuildContext context) {
    return Document(
      head: [
        // 🌟 jaspr_tailwind compila automaticamente styles.tw.css → styles.css
        link(href: 'styles.css', rel: 'stylesheet'),
      ],
      body: div(
        // Use classes Tailwind diretamente; jaspr_tailwind auto-atualiza durante o desenvolvimento
        classes: 'bg-gray-100 min-h-screen flex items-center justify-center',
        [
          h1(classes: 'text-4xl font-bold text-blue-600', [.text('Hello Tailwind!')]),
        ]
      ),
    );
  }
}

3. Roteamento (jaspr_router)

O roteamento do Jaspr espelha o go_router com uma API declarativa.

3.1 Instalação e Configuração

dependencies:
  jaspr_router: ^0.2.0
import 'package:jaspr/jaspr.dart';
import 'package:jaspr_router/jaspr_router.dart';

class MyApp extends StatelessComponent {
  @override
  Component build(BuildContext context) {
    return Router(
      routes: [
        Route(
          path: '/', 
          builder: (context, state) => const HomePage(),
        ),
        Route(
          path: '/about', 
          builder: (context, state) => const AboutPage(),
        ),
      ],
    );
  }
}

4. SSR: Pré-carregamento Assíncrono de Dados no Backend

A principal vantagem do Jaspr sobre o Flutter Web é a renderização no lado do servidor (SSR). Com o Flutter Web, os dados são buscados em initState, causando um estado de carregamento no cliente. Com o SSR do Jaspr, os dados são buscados no servidor antes que o HTML seja enviado ao navegador.

4.1 AsyncStatelessComponent (Apenas Servidor)

Importe jaspr/server.dart para usar AsyncStatelessComponent, que permite um método build assíncrono.

import 'package:jaspr/server.dart'; // 🌟 Import apenas para servidor

class ArticlePage extends AsyncStatelessComponent {
  final String articleId;
  const ArticlePage(this.articleId);

  @override
  Future<Component> build(BuildContext context) async {
    // Executa no lado do servidor; use await livremente para chamadas de banco de dados/API
    final articleData = await Database.fetchArticle(articleId);

    // O navegador recebe HTML totalmente renderizado para conteúdo instantâneo e amigável ao SEO
    return div([
      h1([.text(articleData.title)]),
      p([.text(articleData.content)]),
    ]);
  }
}

4.2 Pré-carregamento com Estado (PreloadStateMixin)

Quando o estado precisa ser preservado, misture PreloadStateMixin:

class MyState extends State<MyStatefulComponent> with PreloadStateMixin {
  
  @override
  Future<void> preloadState() async {
    // Executa no lado do servidor antes do initState(); prepara o estado para hidratação no cliente
    await loadInitialData();
  }
  
  // ...
}

5. Testes (jaspr_test)

jaspr_test cobre testes unitários de componente, resultados SSR e interações no navegador.

5.1 Configuração de Dependência

dart pub add jaspr_test --dev

Como jaspr_test re-exporta o nativo package:test, não é necessário importá-lo separadamente.

5.2 Três Principais Funções de Teste

Devido às complexidades do ambiente HTML/Web, o Jaspr fornece três funções de teste específicas para cada cenário:

testComponents (Teste de Componente em Ambiente Virtual) Teste unitário da lógica do seu Componente em um ambiente simulado puro Dart e sem cabeçalho. Este é o método mais rápido. O uso é muito semelhante ao testWidgets do Flutter.

import 'package:jaspr_test/jaspr_test.dart';

void main() {
  testComponents('Testa se clicar no botão incrementa o contador', (tester) async {
    tester.pumpComponent(MyComponent());
    expect(find.text('Count: 0'), findsOneComponent);
    await tester.click(find.tag('button'));
    expect(find.text('Count: 1'), findsOneComponent);
  });
}

testServer (Teste de Renderização no Lado do Servidor) Destinado a testar aplicações SSR. Ele inicia diretamente um Servidor HTTP local simulado. Você pode enviar Requisições e verificar as strings HTML ou propriedades de estado retornadas pelo Servidor.

import 'package:jaspr_test/jaspr_test.dart';

void main() {
  testServer('Verifica HTML renderizado no servidor', (tester) async {
    final response = await tester.request('/');
    expect(response.document.body?.text, contains('Welcome to SSR'));
  });
}

testClient (Testes de Hidratação e Sincronização de Estado no Navegador) Executa em um ambiente de navegador sem cabeçalho, testando se o cliente assume corretamente via hidratação e lida com interações DOM após receber initialStateData do servidor.

Restrições

  • Use AsyncStatelessComponent apenas no lado do servidor (jaspr/server.dart). Nunca no código de UI do cliente.
  • Não aninhe Widgets do Flutter dentro de Components do Jaspr.
  • Escolha o testador de acordo com seu modo de renderização: SSR → testServer, CSR → testComponents, navegador → testClient. Prefira correspondência de string DOM em vez de tipagem estrita.

Habilidades Relacionadas