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:
# Criar um novo projeto Astronpm create astro@latest my-project
# Navegar para o diretório do projetocd my-project
# Instalar dependências recomendadasnpm install -D tailwindcss @astrojs/tailwind prettier prettier-plugin-astro eslint eslint-plugin-astro typescriptEstrutura 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 TypeScriptConfiguração do Editor
VS Code
Configurações recomendadas para o VS Code:
{ "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
{ "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:
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:
{ "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:
const fs = require('fs');const path = require('path');
// Obter argumentos da linha de comandoconst 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 destinoconst baseDir = path.join(__dirname, '../src/components');const targetDir = path.join(baseDir, componentType);
// Verificar se o diretório existeif (!fs.existsSync(targetDir)) { fs.mkdirSync(targetDir, { recursive: true });}
// Caminho completo para o novo componenteconst componentPath = path.join(targetDir, `${componentName}.astro`);
// Verificar se o componente já existeif (fs.existsSync(componentPath)) { console.error(`O componente ${componentName} já existe em ${componentType}.`); process.exit(1);}
// Template do componenteconst 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 componentefs.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:
# Gerar um componente UInpm run gen:component Button
# Gerar um componente de layoutnpm run gen:component Header layoutAliases 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/*"] } }}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ênciasnode_modules/.pnpm-store/
# Builddist/.output/.astro/
# Logslogs*.lognpm-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:
#!/bin/sh. "$(dirname "$0")/_/husky.sh"
# Verifica se há erros de lintnpm run lint
# Formata o códigonpm run formatConfiguraçã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:
# Instalar Vitest e ferramentas relacionadasnpm install -D vitest jsdom @testing-library/domConfiguraçã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 testesimport { expect, afterEach } from 'vitest';import { cleanup } from '@testing-library/dom';import matchers from '@testing-library/jest-dom/matchers';
// Adiciona matchers personalizadosexpect.extend(matchers);
// Limpa o DOM após cada testeafterEach(() => { 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:
# Instalar Playwrightnpm init playwright@latestConfiguração no playwright.config.js:
// @ts-checkconst { 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:
# Instalar Lighthouse CInpm install -D @lhci/cliArquivo 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:
- Padrões de JavaScript: Organização de funções e módulos
- Testes e Qualidade: Estratégias de teste e garantia de qualidade
- Acessibilidade: Práticas para tornar seu site acessível
Última atualização: 21 de março de 2025