Communitygithub.com

Padrões Vite

Padrões de ferramentas de build Vite, incluindo configuração, plugins, HMR, variáveis de ambiente, proxy, SSR, modo biblioteca, pré-empacotamento de dependências e otimização de build. Ativar ao trabalhar com vite.config.ts, plugins Vite ou projetos baseados em Vite.

O que é Padrões Vite?

Este arquivo de habilidades fornece um guia abrangente de padrões e práticas recomendadas para projetos que utilizam o Vite, um build tool moderno para desenvolvimento web. Ele aborda desde a configuração básica do `vite.config.ts` até tópicos avançados como otimização de build, modo biblioteca, Server-Side Rendering (SSR) e variáveis de ambiente. A habilidade é ativada automaticamente quando você trabalha com arquivos de configuração do Vite, plugins Vite ou em projetos que usam Vite como build tool principal, ajudando a resolver problemas comuns e aplicar boas práticas. O conteúdo cobre plataformas como React, Vue e qualquer projeto que use Vite, com exemplos práticos de código TypeScript e configurações detalhadas. É útil para desenvolvedores que precisam configurar proxies para APIs, publicar bibliotecas com `build.lib`, depurar erros de HMR, otimizar o desempenho do servidor de desenvolvimento ou evitar armadilhas comuns de produção, como variáveis de ambiente expostas incorretamente ou chunks desatualizados após deploy.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/ECC/tree/main/skills/vite-patterns

Perguntar na sua IA favorita

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

Documentação

O que Padrões Vite faz?

Padrões de build tool e servidor de desenvolvimento para projetos Vite 8+. Abrange configuração, variáveis de ambiente, proxy, modo biblioteca, pré-empacotamento de dependências e armadilhas comuns de produção.

Quando Usar

  • Configurando vite.config.ts ou vite.config.js
  • Configurando variáveis de ambiente ou arquivos .env
  • Configurando proxy do servidor de desenvolvimento para backends de API
  • Otimizando a saída do build (chunks, minificação, assets)
  • Publicando bibliotecas com build.lib
  • Resolvendo problemas de pré-empacotamento de dependências ou interoperabilidade CJS/ESM
  • Depurando HMR, servidor de desenvolvimento ou erros de build
  • Escolhendo ou ordenando plugins Vite

Como Funciona

  • Modo dev serve arquivos fonte como ESM nativo — sem empacotamento. As transformações acontecem sob demanda por requisição de módulo, por isso as inicializações a frio são rápidas e o HMR é preciso.
  • Modo build usa Rolldown (v7+) ou Rollup (v5–v6) para empacotar o aplicativo para produção com tree-shaking, code-splitting e minificação baseada em Oxc.
  • Pré-empacotamento de dependências converte dependências CJS/UMD para ESM uma vez via esbuild e armazena o resultado em cache em node_modules/.vite, para que inicializações subsequentes ignorem esse trabalho.
  • Plugins compartilham uma interface unificada entre dev e build — o mesmo objeto de plugin funciona tanto para as transformações sob demanda do servidor de desenvolvimento quanto para o pipeline de produção.
  • Variáveis de ambiente são inlineadas estaticamente no momento do build. Variáveis prefixadas com VITE_ tornam-se constantes públicas no bundle; tudo sem prefixo é invisível para o código cliente.

Exemplos

Estrutura de Configuração

Configuração Básica

// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: { '@': new URL('./src', import.meta.url).pathname },
  },
})

Configuração Condicional

// vite.config.ts
import { defineConfig, loadEnv } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig(({ command, mode }) => {
  const env = loadEnv(mode, process.cwd())   // Apenas prefixo VITE_ (seguro)

  return {
    plugins: [react()],
    server: command === 'serve' ? { port: 3000 } : undefined,
    define: {
      __API_URL__: JSON.stringify(env.VITE_API_URL),
    },
  }
})

Opções Chave de Configuração

ChavePadrãoDescrição
root'.'Raiz do projeto (onde index.html reside)
base'/'Caminho base público para assets implantados
envPrefix'VITE_'Prefixo para variáveis de ambiente expostas ao cliente
build.outDir'dist'Diretório de saída
build.minify'oxc'Minificador ('oxc', 'terser' ou false)
build.sourcemapfalsetrue, 'inline' ou 'hidden'

Plugins

Plugins Essenciais

A maioria das necessidades de plugins é coberta por alguns pacotes bem mantidos. Recorra a estes antes de escrever o seu próprio.

PluginPropósitoQuando usar
@vitejs/plugin-react-swcReact HMR + Fast Refresh via SWCPadrão para aplicativos React (mais rápido que a variante Babel)
@vitejs/plugin-reactReact HMR + Fast Refresh via BabelApenas se precisar de plugins Babel (emotion, decorators MobX)
@vitejs/plugin-vueSuporte a Vue 3 SFCAplicativos Vue
vite-plugin-checkerExecuta tsc + ESLint em thread de worker com overlay HMRQualquer aplicativo TypeScript — Vite NÃO faz verificação de tipos durante vite build
vite-tsconfig-pathsHonra aliases paths do tsconfig.jsonQualquer momento em que você já tenha aliases em tsconfig.json
vite-plugin-dtsEmite arquivos .d.ts no modo bibliotecaPublicando bibliotecas TypeScript
vite-plugin-svgrImporta SVGs como componentes ReactAplicativos React que usam SVGs como componentes
rollup-plugin-visualizerRelatório de treemap/sunburst do bundleAuditorias periódicas de tamanho do bundle (use enforce: 'post')
vite-plugin-pwaPWA + Workbox sem configuraçãoAplicativos com suporte offline

Observação crítica: vite build transpila, mas NÃO faz verificação de tipos. Erros de tipo são enviados silenciosamente para produção a menos que você adicione vite-plugin-checker ou execute tsc --noEmit no CI.

Criando Plugins Personalizados

Criar plugins é raro — a maioria das necessidades é coberta por plugins existentes. Quando precisar de um, comece inline em vite.config.ts e extraia apenas se for reutilizado.

// vite.config.ts — plugin inline mínimo
function myPlugin(): Plugin {
  return {
    name: 'my-plugin',                       // obrigatório, deve ser único
    enforce: 'pre',                           // 'pre' | 'post' (opcional)
    apply: 'build',                           // 'build' | 'serve' (opcional)
    transform(code, id) {
      if (!id.endsWith('.custom')) return
      return { code: transformCustom(code), map: null }
    },
  }
}

Hooks principais: transform (modificar fonte), resolveId + load (módulos virtuais), transformIndexHtml (injetar no HTML), configureServer (adicionar middleware de dev), hotUpdate (HMR personalizado — substitui o handleHotUpdate obsoleto no v7+).

Módulos virtuais usam a convenção de prefixo \0 — resolveId retorna '\0virtual:my-id' para que outros plugins o ignorem. O código do usuário importa 'virtual:my-id'.

Para a API completa de plugins, consulte vite.dev/guide/api-plugin. Use vite-plugin-inspect durante o desenvolvimento para depurar o pipeline de transformação.

API HMR

Plugins de framework (@vitejs/plugin-react, @vitejs/plugin-vue, etc.) lidam com HMR automaticamente. Recorra a import.meta.hot diretamente apenas ao construir stores de estado personalizados, ferramentas de desenvolvimento ou utilitários agnósticos de framework que precisam persistir estado entre atualizações.

// src/store.ts — HMR manual para um módulo vanilla
if (import.meta.hot) {
  // Persistir estado entre atualizações (deve MUTAR, nunca reatribuir .data)
  import.meta.hot.data.count = import.meta.hot.data.count ?? 0

  // Limpar efeitos colaterais antes de o módulo ser substituído
  import.meta.hot.dispose((data) => clearInterval(data.intervalId))

  // Aceitar atualizações deste módulo
  import.meta.hot.accept()
}

Todo código import.meta.hot é removido por tree-shaking nos builds de produção — nenhuma remoção de guarda é necessária.

Variáveis de Ambiente

Vite carrega .env, .env.local, .env.[mode] e .env.[mode].local nesta ordem (as posteriores substituem as anteriores); arquivos *.local são ignorados pelo git e destinam-se a segredos locais.

Acesso do Lado do Cliente

Apenas variáveis prefixadas com VITE_ são expostas ao código cliente:

import.meta.env.VITE_API_URL   // string
import.meta.env.MODE            // 'development' | 'production' | custom
import.meta.env.BASE_URL        // valor da configuração base
import.meta.env.DEV             // boolean
import.meta.env.PROD            // boolean
import.meta.env.SSR             // boolean

Usando Env na Configuração

// vite.config.ts
import { defineConfig, loadEnv } from 'vite'

export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd())          // Apenas prefixo VITE_ (seguro)
  return {
    define: {
      __API_URL__: JSON.stringify(env.VITE_API_URL),
    },
  }
})

Segurança

Prefixo VITE_ NÃO é um Limite de Segurança

Qualquer variável prefixada com VITE_ é inlineada estaticamente no bundle do cliente no momento do build. Minificação, codificação base64 e desabilitação de source maps NÃO a ocultam. Um atacante determinado pode extrair qualquer variável VITE_ do JavaScript enviado.

Regra: Apenas valores públicos (URLs de API, flags de funcionalidade, chaves públicas) vão em variáveis VITE_. Segredos (tokens de API, URLs de banco de dados, chaves privadas) DEVEM viver no lado do servidor, por trás de uma API ou função serverless.

A Armadilha de loadEnv('')

// RUIM: passar '' como terceiro argumento carrega TODAS as variáveis de ambiente — incluindo segredos do servidor —
// e as torna disponíveis para serem inlineadas no código cliente via `define`.
const env = loadEnv(mode, process.cwd(), '')

// BOM: lista explícita de prefixos
const env = loadEnv(mode, process.cwd(), ['VITE_', 'APP_'])

Source Maps em Produção

Source maps de produção vazam seu código fonte original. Desabilite-os a menos que os envie para um rastreador de erros (Sentry, Bugsnag) e os exclua localmente depois:

build: {
  sourcemap: false,                                  // padrão — mantenha assim
}

Checklist .gitignore

  • .env.local, .env.*.local — substituições de segredos locais
  • dist/ — saída do build
  • node_modules/.vite — cache de pré-empacotamento (entradas obsoletas causam erros fantasmas)

Proxy do Servidor

// vite.config.ts — server.proxy
server: {
  proxy: {
    '/foo': 'http://localhost:4567',                    // atalho de string

    '/api': {
      target: 'http://localhost:8080',
      changeOrigin: true,                               // necessário para backends com host virtual
      rewrite: (path) => path.replace(/^\/api/, ''),
    },
  },
}

Para proxy WebSocket, adicione ws: true à configuração da rota.

Otimização de Build

Chunks Manuais

// vite.config.ts — build.rolldownOptions
build: {
  rolldownOptions: {
    output: {
      // Forma de objeto: agrupar pacotes específicos
      manualChunks: {
        'react-vendor': ['react', 'react-dom'],
        'ui-vendor': ['@radix-ui/react-dialog', '@radix-ui/react-popover'],
      },
    },
  },
}
// Forma de função: dividir por heurística
manualChunks(id) {
  if (id.includes('node_modules/react')) return 'react-vendor'
  if (id.includes('node_modules')) return 'vendor'
}

Desempenho

Evite Arquivos Barrel

Arquivos barrel (index.ts reexportando tudo de um diretório) forçam o Vite a carregar cada arquivo reexportado mesmo quando você importa um único símbolo. Esta é a causa #1 de lentidão no servidor de desenvolvimento sinalizada pela documentação oficial.

// RUIM — importar um util força o Vite a carregar todo o barrel
import { slash } from '@/utils'

// BOM — importação direta, apenas o arquivo é carregado
import { slash } from '@/utils/slash'

Seja Explícito com Extensões de Importação

Cada extensão implícita força até 6 verificações no sistema de arquivos via resolve.extensions. Em bases de código grandes, isso se acumula.

// RUIM
import Component from './Component'

// BOM
import Component from './Component.tsx'

Restrinja tsconfig.json allowImportingTsExtensions + resolve.extensions apenas às extensões que você realmente usa.

Aquecimento de Rotas de Caminho Quente

server.warmup.clientFiles pré-transforma entradas quentes conhecidas antes de o navegador solicitá-las — eliminando a cascata de requisições de carregamento a frio em aplicativos grandes.

// vite.config.ts
server: {
  warmup: {
    clientFiles: ['./src/main.tsx', './src/routes/**/*.tsx'],
  },
}

Perfilando Servidores de Desenvolvimento Lentos

Quando vite dev parece lento, comece com vite --profile, interaja com o aplicativo, depois pressione p+enter para salvar um .cpuprofile. Carregue-o no Speedscope para descobrir quais plugins estão consumindo tempo — geralmente hooks buildStart, config ou configResolved em plugins da comunidade.

Modo Biblioteca

Ao publicar um pacote npm, use build.lib. Duas armadilhas importam mais do que detalhes de configuração:

  1. Tipos não são emitidos — adicione vite-plugin-dts ou execute tsc --emitDeclarationOnly separadamente.
  2. Dependências pares DEVEM ser externalizadas — pares não listados são empacotados em sua biblioteca, causando erros de runtime duplicado em consumidores.
// vite.config.ts
build: {
  lib: {
    entry: 'src/index.ts',
    formats: ['es', 'cjs'],
    fileName: (format) => `my-lib.${format}.js`,
  },
  rolldownOptions: {
    external: ['react', 'react-dom', 'react/jsx-runtime'],  // toda dependência par
  },
}

Externals SSR

Configurações simples de createServer({ middlewareMode: true }) são território de autores de framework. A maioria dos aplicativos deve usar Nuxt, Remix, SvelteKit, Astro ou TanStack Start. O que você ajustará como usuário de framework é a configuração de externals quando dependências quebram em SSR:

// vite.config.ts — opções ssr
ssr: {
  external: ['node-native-package'],           // manter como require() no bundle SSR
  noExternal: ['esm-only-package'],            // forçar empacotamento na saída SSR (corrige a maioria dos erros SSR)
  target: 'node',                              // 'node' ou 'webworker'
}

Pré-empacotamento de Dependências

Vite pré-empacota dependências para converter CJS/UMD para ESM e reduzir o número de requisições.

// vite.config.ts — optimizeDeps
optimizeDeps: {
  include: [
    'lodash-es',                              // forçar pré-empacotamento de dependências pesadas conhecidas
    'cjs-package',                            // dependências CJS que causam problemas de interop
    'deep-lib/components/**',                 // glob para imports profundos
  ],
  exclude: ['local-esm-package'],             // deve ser ESM válido se excluído
  force: true,                                // ignorar cache, re-otimizar (depuração temporária)
}

Armadilhas Comuns

Dev Não Corresponde ao Build

Dev usa esbuild/Rolldown para transformações; build usa Rolldown para empacotamento. Bibliotecas CJS podem se comportar de forma diferente entre os dois. Sempre verifique com vite build && vite preview antes de implantar.

Chunks Obsoletos Após Implantação

Novos builds produzem novos hashes de chunks. Usuários com sessões ativas solicitam nomes de arquivos antigos que não existem mais. Vite não tem solução embutida. Mitigações:

  • Mantenha arquivos antigos de dist/assets/ vivos por uma janela de implantação
  • Capture erros de importação dinâmica em seu roteador e force um recarregamento de página

Docker e Contêineres

Vite vincula a localhost por padrão, que é inacessível de fora de um contêiner:

// vite.config.ts — configuração Docker/contêiner
server: {
  host: true,                                  // vincular 0.0.0.0
  hmr: { clientPort: 3000 },                   // se atrás de um proxy reverso
}

Acesso a Arquivos em Monorepo

Vite restringe o serviço de arquivos à raiz do projeto. Pacotes fora da raiz são bloqueados:

// vite.config.ts — acesso a arquivos em monorepo
server: {
  fs: {
    allow: ['..'],                             // permitir diretório pai (raiz do workspace)
  },
}

Anti-Padrões

// RUIM: Definir envPrefix como '' expõe TODAS as variáveis de ambiente (incluindo segredos) ao cliente
envPrefix: ''

// RUIM: Assumir que require() funciona em código do cliente

// RUIM: Ignorar erros de HMR no console

Resolução de Problemas

HMR Não Funciona

  1. Verifique se o plugin do framework está instalado e incluído
  2. Certifique-se de que a exportação nomeada do componente corresponda ao nome do arquivo
  3. Verifique se não há erros de sintaxe no console do navegador
  4. Tente vite --force para limpar o cache de pré-empacotamento

Erros de Build

# Erro: "Build failed with 1 error"
# Verifique a mensagem de erro completa — geralmente é um erro de sintaxe ou tipo

# Erro: "Could not resolve"
# Verifique se o caminho de importação está correto e se o pacote está instalado

# Erro: "Out of memory"
# Aumente a memória do Node.js: NODE_OPTIONS="--max-old-space-size=4096" vite build

Ferramentas de Diagnóstico

  • vite --debug — modo de depuração detalhada
  • vite-plugin-inspect — inspecionar pipeline de transformação (http://localhost:5173/__inspect)
  • debugger no código fonte — funciona com HMR
  • console.log com source maps ativados

Referências

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/content-engine

Create platform-native content systems for X, LinkedIn, TikTok, YouTube, newsletters, and repurposed multi-platform campaigns. Use when the user wants social posts, threads, scripts, content calendars, or one source asset adapted cleanly across platforms.

affaan-m/ECC

Multi-platform content distribution across X, LinkedIn, Threads, and Bluesky. Adapts content per platform using content-engine patterns. Never posts identical content cross-platform. Use when the user wants to distribute content across social platforms.

affaan-m/fal-ai-media

Unified media generation via fal.ai MCP — image, video, and audio. Covers text-to-image (Nano Banana), text/image-to-video (Seedance, Kling, Veo 3), text-to-speech (CSM-1B), and video-to-audio (ThinkSound). Use when the user wants to generate images, videos, or audio with AI.

affaan-m/manim-video

日本語翻訳:このファイルは manim-video 用の日本語翻訳が必要です

affaan-m/remotion-video-creation

Remotion のベストプラクティス - React で動画を作成する。3D、アニメーション、音声、字幕、チャート、トランジションなどをカバーするドメイン固有の29のルール。

affaan-m/video-editing

AI-assisted video editing workflows for cutting, structuring, and augmenting real footage. Covers the full pipeline from raw capture through FFmpeg, Remotion, ElevenLabs, fal.ai, and final polish in Descript or CapCut. Use when the user wants to edit video, cut footage, create vlogs, or build video content.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

agent-self-evaluation

Use after completing any non-trivial task. The agent self-rates its output on 5 axes — accuracy, completeness, clarity, actionability, conciseness — with concrete evidence per criterion. Produces a structured 1-5 scorecard with specific improvement suggestions.

agent-sort

Build an evidence-backed ECC install plan for a specific repo by sorting skills, commands, rules, hooks, and extras into DAILY vs LIBRARY buckets using parallel repo-aware review passes. Use when ECC should be trimmed to what a project actually needs instead of loading the full bundle.

ai-first-engineering

Engineering operating model for teams where AI agents generate a large share of implementation output. Use when setting team process, review gates, or ownership rules for a codebase largely written by agents.

ai-regression-testing

Regression testing strategies for AI-assisted development. Sandbox-mode API testing without database dependencies, automated bug-check workflows, and patterns to catch AI blind spots where the same model writes and reviews code. Use when adding regression coverage to AI-assisted code, or when the same model both wrote and reviewed a change.

android-clean-architecture

Clean Architecture patterns for Android and Kotlin Multiplatform projects — module structure, dependency rules, UseCases, Repositories, and data layer patterns. Use when structuring modules, layers, or data flow in an Android or KMP project.

angular-developer

Generates Angular code and provides architectural guidance. Trigger when creating projects, components, or services, or for best practices on reactivity (signals, linkedSignal, resource), forms, dependency injection, routing, SSR, accessibility (ARIA), animations, styling (component styles, Tailwind CSS), testing, or CLI tooling.

Habilidades Relacionadas