Pular para o conteúdo

9. Ferramentas de Desenvolvimento

Este documento detalha as ferramentas recomendadas para o desenvolvimento de soluções web com Astro 5, incluindo configurações, extensões e utilitários que melhoram a produtividade e a qualidade do código.

Ambiente de Desenvolvimento

Configuração Inicial

Para iniciar um novo projeto Astro com as configurações recomendadas:

Terminal window
# Criar um novo projeto Astro
npm create astro@latest my-project
# Navegar para o diretório do projeto
cd my-project
# Instalar dependências recomendadas
npm install -D tailwindcss @astrojs/tailwind prettier prettier-plugin-astro eslint eslint-plugin-astro typescript

Estrutura de Projeto Recomendada

my-project/
├── .vscode/ # Configurações do VS Code
│ ├── extensions.json # Extensões recomendadas
│ └── settings.json # Configurações do editor
├── public/ # Arquivos estáticos
├── src/
│ ├── assets/ # Imagens, fontes, etc.
│ ├── components/ # Componentes reutilizáveis
│ │ ├── ui/ # Componentes de UI
│ │ ├── layout/ # Componentes de layout
│ │ └── interactive/ # Componentes interativos
│ ├── content/ # Content Collections
│ ├── layouts/ # Layouts de página
│ ├── pages/ # Páginas e endpoints
│ ├── scripts/ # Scripts do cliente
│ ├── styles/ # Estilos globais
│ └── utils/ # Funções utilitárias
├── .eslintrc.js # Configuração do ESLint
├── .prettierrc # Configuração do Prettier
├── astro.config.mjs # Configuração do Astro
├── package.json # Dependências e scripts
├── tailwind.config.js # Configuração do Tailwind
└── tsconfig.json # Configuração do TypeScript

Configuração do Editor

VS Code

Configurações recomendadas para o VS Code:

.vscode/settings.json
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"eslint.validate": [
"javascript",
"javascriptreact",
"astro",
"typescript",
"typescriptreact"
],
"prettier.documentSelectors": ["**/*.astro"],
"[astro]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"emmet.includeLanguages": {
"astro": "html"
},
"tailwindCSS.includeLanguages": {
"astro": "html"
},
"files.associations": {
"*.mdx": "markdown"
}
}

Extensões Recomendadas

.vscode/extensions.json
{
"recommendations": [
"astro-build.astro-vscode",
"bradlc.vscode-tailwindcss",
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"unifiedjs.vscode-mdx",
"streetsidesoftware.code-spell-checker",
"csstools.postcss",
"formulahendry.auto-rename-tag",
"formulahendry.auto-close-tag",
"mikestead.dotenv"
]
}

Linting e Formatação

ESLint

Configuração recomendada para ESLint:

.eslintrc.js
module.exports = {
extends: [
'eslint:recommended',
'plugin:astro/recommended',
],
overrides: [
{
// Define as configurações para arquivos Astro
files: ['*.astro'],
parser: 'astro-eslint-parser',
parserOptions: {
parser: '@typescript-eslint/parser',
extraFileExtensions: ['.astro'],
},
rules: {
// Regras específicas para arquivos Astro
},
},
{
// Define as configurações para arquivos TypeScript
files: ['*.ts', '*.tsx'],
parser: '@typescript-eslint/parser',
extends: [
'plugin:@typescript-eslint/recommended',
],
rules: {
// Regras específicas para TypeScript
},
},
{
// Define as configurações para arquivos JavaScript
files: ['*.js', '*.jsx'],
rules: {
// Regras específicas para JavaScript
},
},
],
};

Prettier

Configuração recomendada para Prettier:

.prettierrc
{
"printWidth": 100,
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"useTabs": false,
"plugins": ["prettier-plugin-astro"],
"overrides": [
{
"files": "*.astro",
"options": {
"parser": "astro"
}
}
]
}

Ferramentas de Build e Desenvolvimento

Scripts NPM

Scripts recomendados para o package.json:

{
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro build",
"preview": "astro preview",
"astro": "astro",
"lint": "eslint . --ext .js,.jsx,.ts,.tsx,.astro",
"lint:fix": "eslint . --ext .js,.jsx,.ts,.tsx,.astro --fix",
"format": "prettier --write .",
"check": "astro check && tsc --noEmit"
}
}

Configuração do Astro

Configuração recomendada para astro.config.mjs:

import { defineConfig } from 'astro/config';
import tailwind from '@astrojs/tailwind';
export default defineConfig({
integrations: [
tailwind({
// Configuração do Tailwind
config: { path: './tailwind.config.js' },
}),
],
vite: {
// Configurações do Vite
build: {
// Otimizações de build
cssCodeSplit: true,
minify: 'terser',
terserOptions: {
compress: {
drop_console: true, // Remove console.log em produção
},
},
},
server: {
// Configurações do servidor de desenvolvimento
hmr: true,
watch: {
usePolling: false,
},
},
},
server: {
// Configurações do servidor Astro
port: 3000,
host: true, // Permite acesso externo
},
output: 'static', // 'static' (padrão) ou 'server' para SSR
});

Configuração do Tailwind CSS

Configuração recomendada para tailwind.config.js:

/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
theme: {
extend: {
colors: {
primary: {
50: '#f0f9ff',
100: '#e0f2fe',
200: '#bae6fd',
300: '#7dd3fc',
400: '#38bdf8',
500: '#0ea5e9',
600: '#0284c7',
700: '#0369a1',
800: '#075985',
900: '#0c4a6e',
950: '#082f49',
},
// Adicione outras cores personalizadas aqui
},
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
// Adicione outras famílias de fontes aqui
},
spacing: {
// Espaçamentos personalizados
},
borderRadius: {
// Raios de borda personalizados
},
// Outras extensões do tema
},
},
plugins: [
require('@tailwindcss/typography'), // Opcional: para estilos de conteúdo rico
require('@tailwindcss/forms'), // Opcional: para estilos de formulários
],
};

Ferramentas de Produtividade

Geração de Componentes

Crie um script para gerar novos componentes com um template consistente:

scripts/generate-component.js
const fs = require('fs');
const path = require('path');
// Obter argumentos da linha de comando
const args = process.argv.slice(2);
const componentName = args[0];
const componentType = args[1] || 'ui'; // Padrão: ui
if (!componentName) {
console.error('Por favor, forneça um nome para o componente.');
process.exit(1);
}
// Definir diretório de destino
const baseDir = path.join(__dirname, '../src/components');
const targetDir = path.join(baseDir, componentType);
// Verificar se o diretório existe
if (!fs.existsSync(targetDir)) {
fs.mkdirSync(targetDir, { recursive: true });
}
// Caminho completo para o novo componente
const componentPath = path.join(targetDir, `${componentName}.astro`);
// Verificar se o componente já existe
if (fs.existsSync(componentPath)) {
console.error(`O componente ${componentName} já existe em ${componentType}.`);
process.exit(1);
}
// Template do componente
const componentTemplate = `---
/**
* ${componentName} Component
*
* @description Breve descrição do componente
*/
interface Props {
// Defina as props do componente aqui
class?: string;
}
const { class: className = '' } = Astro.props;
---
<div class={className}>
<!-- Conteúdo do componente -->
<p>${componentName} works!</p>
</div>
<style>
/* Estilos específicos do componente */
</style>
`;
// Escrever o arquivo do componente
fs.writeFileSync(componentPath, componentTemplate);
console.log(`✅ Componente ${componentName} criado em ${componentPath}`);

Adicione o script ao package.json:

{
"scripts": {
// ... outros scripts
"gen:component": "node scripts/generate-component.js"
}
}

Uso:

Terminal window
# Gerar um componente UI
npm run gen:component Button
# Gerar um componente de layout
npm run gen:component Header layout

Aliases de Importação

Configure aliases para facilitar importações:

// tsconfig.json
{
"compilerOptions": {
// ... outras opções
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@components/*": ["src/components/*"],
"@layouts/*": ["src/layouts/*"],
"@utils/*": ["src/utils/*"],
"@styles/*": ["src/styles/*"],
"@assets/*": ["src/assets/*"]
}
}
}
astro.config.mjs
import { defineConfig } from 'astro/config';
import { fileURLToPath } from 'url';
export default defineConfig({
// ... outras configurações
vite: {
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
'@components': fileURLToPath(new URL('./src/components', import.meta.url)),
'@layouts': fileURLToPath(new URL('./src/layouts', import.meta.url)),
'@utils': fileURLToPath(new URL('./src/utils', import.meta.url)),
'@styles': fileURLToPath(new URL('./src/styles', import.meta.url)),
'@assets': fileURLToPath(new URL('./src/assets', import.meta.url)),
},
},
},
});

Controle de Versão

Configuração do Git

Arquivo .gitignore recomendado:

# Dependências
node_modules/
.pnpm-store/
# Build
dist/
.output/
.astro/
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Ambiente
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
# Editor
.vscode/*
!.vscode/extensions.json
!.vscode/settings.json
.idea/
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

Hooks do Git

Crie hooks para garantir qualidade do código antes de commits:

.husky/pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
# Verifica se há erros de lint
npm run lint
# Formata o código
npm run format

Configuração no package.json:

{
"scripts": {
// ... outros scripts
"prepare": "husky install"
},
"devDependencies": {
// ... outras dependências
"husky": "^8.0.0"
}
}

Ferramentas de Teste

Vitest

Configuração para testes unitários com Vitest:

Terminal window
# Instalar Vitest e ferramentas relacionadas
npm install -D vitest jsdom @testing-library/dom

Configuração no vitest.config.js:

import { defineConfig } from 'vitest/config';
import { fileURLToPath } from 'url';
export default defineConfig({
test: {
environment: 'jsdom',
globals: true,
setupFiles: ['./vitest.setup.js'],
include: ['src/**/*.test.{js,ts}'],
coverage: {
reporter: ['text', 'json', 'html'],
exclude: ['node_modules/', 'src/**/*.d.ts'],
},
},
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
'@components': fileURLToPath(new URL('./src/components', import.meta.url)),
'@utils': fileURLToPath(new URL('./src/utils', import.meta.url)),
},
},
});

Arquivo de setup vitest.setup.js:

// Configurações globais para testes
import { expect, afterEach } from 'vitest';
import { cleanup } from '@testing-library/dom';
import matchers from '@testing-library/jest-dom/matchers';
// Adiciona matchers personalizados
expect.extend(matchers);
// Limpa o DOM após cada teste
afterEach(() => {
cleanup();
});

Scripts no package.json:

{
"scripts": {
// ... outros scripts
"test": "vitest run",
"test:watch": "vitest",
"test:coverage": "vitest run --coverage"
}
}

Playwright

Configuração para testes end-to-end com Playwright:

Terminal window
# Instalar Playwright
npm init playwright@latest

Configuração no playwright.config.js:

// @ts-check
const { defineConfig, devices } = require('@playwright/test');
/**
* @see https://playwright.dev/docs/test-configuration
*/
module.exports = defineConfig({
testDir: './tests/e2e',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: [['html', { open: 'never' }]],
use: {
baseURL: 'http://localhost:3000',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
},
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
{
name: 'mobile-chrome',
use: { ...devices['Pixel 5'] },
},
{
name: 'mobile-safari',
use: { ...devices['iPhone 12'] },
},
],
webServer: {
command: 'npm run preview',
port: 3000,
reuseExistingServer: !process.env.CI,
},
});

Scripts no package.json:

{
"scripts": {
// ... outros scripts
"test:e2e": "playwright test",
"test:e2e:ui": "playwright test --ui"
}
}

Ferramentas de Análise

Lighthouse CI

Configuração para Lighthouse CI:

Terminal window
# Instalar Lighthouse CI
npm install -D @lhci/cli

Arquivo de configuração lighthouserc.js:

module.exports = {
ci: {
collect: {
url: ['http://localhost:3000/', 'http://localhost:3000/about'],
startServerCommand: 'npm run preview',
numberOfRuns: 3,
},
upload: {
target: 'temporary-public-storage',
},
assert: {
preset: 'lighthouse:recommended',
assertions: {
'categories:performance': ['error', { minScore: 0.9 }],
'categories:accessibility': ['error', { minScore: 0.9 }],
'categories:best-practices': ['error', { minScore: 0.9 }],
'categories:seo': ['error', { minScore: 0.9 }],
},
},
},
};

Script no package.json:

{
"scripts": {
// ... outros scripts
"lighthouse": "lhci autorun"
}
}

Ferramentas de Implantação

Netlify

Arquivo de configuração netlify.toml:

[build]
command = "npm run build"
publish = "dist"
[dev]
command = "npm run dev"
port = 3000
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
[build.environment]
NODE_VERSION = "18"

Vercel

Arquivo de configuração vercel.json:

{
"buildCommand": "npm run build",
"outputDirectory": "dist",
"devCommand": "npm run dev",
"installCommand": "npm install",
"framework": "astro",
"github": {
"silent": true
}
}

Conclusão

As ferramentas e configurações apresentadas neste documento fornecem uma base sólida para o desenvolvimento de soluções web com Astro 5. Ao seguir estas recomendações, você pode criar um ambiente de desenvolvimento eficiente e produtivo, garantindo a qualidade e a consistência do código.

Lembre-se de adaptar estas configurações às necessidades específicas do seu projeto, adicionando ou removendo ferramentas conforme necessário.

Os próximos documentos detalharão outros aspectos do desenvolvimento:


Última atualização: 21 de março de 2025