Communitygithub.com

vite-patterns

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

O que é vite-patterns?

Este skill fornece padrões e práticas recomendadas para projetos que utilizam o Vite (versão 5+), abordando desde configurações básicas até tópicos avançados como otimização de build, modo biblioteca e SSR. Ele é útil para desenvolvedores que configuram `vite.config.ts`, lidam com variáveis de ambiente, configuram proxy para APIs, publicam bibliotecas ou enfrentam problemas comuns como diferenças entre dev e produção, chunks desatualizados ou dependências CJS/ESM. O skill cobre os principais fluxos do Vite: o modo dev (ESM nativo sem bundling, transformações sob demanda) e o modo build (Rolldown ou Rollup para produção com tree-shaking e minificação). Inclui exemplos práticos de configuração, plugins essenciais, autorização de plugins customizados, API HMR manual, variáveis de ambiente (incluindo segurança com o prefixo VITE_), proxy do servidor, otimização de chunks, modo biblioteca, SSR, pré-agrupamento de dependências e uma seção de anti-padrões. O conteúdo é voltado para desenvolvedores que já conhecem o básico do Vite e precisam de orientação detalhada para cenários reais e otimização de performance.

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

Perguntar na sua IA favorita

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

Documentação

Padrões Vite

Padrões de ferramenta de build e servidor de desenvolvimento para projetos Vite 5+. Abrange configuração, variáveis de ambiente, proxy, modo biblioteca, pré-agrupamento 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é-agrupamento de dependências ou interoperabilidade CJS/ESM
  • Depurando erros de HMR, servidor de desenvolvimento ou build
  • Escolhendo ou ordenando plugins Vite

Como Funciona

  • Modo dev serve arquivos fonte como ESM nativo — sem bundling. As transformações acontecem sob demanda por requisição de módulo, razão pela qual as inicializações a frio são rápidas e o HMR é preciso.
  • Modo build usa o Rolldown (v7+) ou Rollup (v5–v6) para agrupar o aplicativo para produção com tree-shaking, divisão de código e minificação baseada em Oxc.
  • Pré-agrupamento de dependências converte dependências CJS/UMD para ESM uma vez via esbuild e armazena o resultado em cache sob node_modules/.vite, para que inicializações subsequentes pulem o 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 de Configuração Principais

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 um punhado de pacotes bem mantidos. Recorra a estes antes de escrever os seus próprios.

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, decoradores MobX)
@vitejs/plugin-vueSuporte a Vue 3 SFCAplicativos Vue
vite-plugin-checkerExecuta tsc + ESLint em thread worker com overlay HMRQualquer aplicativo TypeScript — Vite NÃO faz verificação de tipos durante vite build
vite-tsconfig-pathsHonra aliases de paths do tsconfig.jsonSempre que você já tiver aliases em tsconfig.json
vite-plugin-dtsEmite arquivos .d.ts no modo bibliotecaPublicando bibliotecas TypeScript
vite-plugin-svgrImporta SVGs como componentes ReactAplicativos React usando SVGs como componentes
rollup-plugin-visualizerRelatório de treemap/sunburst do bundleAuditorias periódicas de tamanho do bundle (use enforce: 'post')
vite-plugin-pwaPWA com configuração zero + WorkboxAplicativos com capacidade offline

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

Autorizando Plugins Customizados

Autorizar é 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 desenvolvimento), hotUpdate (HMR personalizado — substitui o obsoleto handleHotUpdate na 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, veja 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 personalizadas, 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 do módulo ser substituído
  import.meta.hot.dispose((data) => clearInterval(data.intervalId))

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

Todo código import.meta.hot é tree-shaken 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 nessa ordem (posterior substitui anterior); arquivos *.local são gitignorados e destinados 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             // booleano
import.meta.env.PROD            // booleano
import.meta.env.SSR             // booleano

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 residir no lado do servidor por trás de uma API ou função serverless.

A Armadilha loadEnv('')

// RUIM: passar '' como terceiro argumento carrega TODAS as variáveis de ambiente — incluindo segredos do servidor —
// e as disponibiliza para inline 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 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é-agrupamento (entradas obsoletas causam erros fantasmas)

Proxy do Servidor

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

    '/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'
}

Performance

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 #1 lentidão do servidor de desenvolvimento apontada 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 de sistema de arquivos via resolve.extensions. Em codebases grandes, isso se acumula.

// RUIM
import Component from './Component'

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

Reduza tsconfig.json allowImportingTsExtensions + resolve.extensions para apenas as extensões que você realmente usa.

Pré-Aqueça Rotas de Caminho Quente

server.warmup.clientFiles pré-transforma entradas quentes conhecidas antes do navegador solicitá-las — eliminando a cascata de requisições de carga 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 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 são mais importantes 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 agrupados 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
  },
}

Externalizações 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 externalizações 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 agrupamento na saída SSR (corrige a maioria dos erros SSR)
  target: 'node',                              // 'node' ou 'webworker'
}

Pré-Agrupamento de Dependências

Vite pré-agrupa 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é-agrupamento de dependências pesadas conhecidas
    'cjs-package',                            // dependências CJS que causam problemas de interoperabilidade
    'deep-lib/components/**',                 // glob para importações profundas
  ],
  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 bundling. 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 chunk. 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:

  • Manter arquivos antigos de dist/assets/ ativos por uma janela de implantação
  • Capturar erros de importação dinâmica no seu roteador e forçar 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 por trá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 módulos ESM — Vite usa ESM nativo no modo dev
// Use importações estáticas com import, ou dynamic imports com await import()

// RUIM: Modificar o objeto options retornado após o retorno da função de configuração
// Pode causar comportamento imprevisível. Sempre retorne um novo objeto.

// RUIM: Usar import.meta.env diretamente em código servidor (SSR node) sem verificar guardas
// No SSR node, import.meta.env.BASE_URL é resolvido, mas a verificação de guarda é recomendada.

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/claude-api

Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.

affaan-m/everything-claude-code

End-to-end marketing campaign planning and execution. Covers audience research, positioning, campaign angle definition, landing page copy, email sequences, social posts, ad copy, short-form video scripts, and content calendars. Use as the orchestration layer for multi-channel product launches. Use when planning or executing a multi-channel product launch, or producing landing page, email, social, or ad copy.

affaan-m/everything-claude-code

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/everything-claude-code-conventions

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/frontend-design

Create distinctive, production-grade frontend interfaces with high design quality. Use when the user asks to build web components, pages, or applications and the visual direction matters as much as the code quality.

affaan-m/gget

gget CLI and Python workflow for quick genomic database queries, sequence lookup, BLAST-style searches, enrichment checks, and reproducible bioinformatics evidence logs.

affaan-m/literature-review

Systematic literature-review workflow for academic, biomedical, technical, and scientific topics, including search planning, source screening, synthesis, citation checks, and evidence logging.

affaan-m/motion-ui

Production-ready UI motion system for React/Next.js. Use when implementing animations, transitions, or motion patterns.

affaan-m/project-guidelines-example

Example project-specific skill template based on a real production application.

affaan-m/pubmed-database

Direct PubMed and NCBI E-utilities search workflows for biomedical literature, MeSH queries, PMID lookup, citation retrieval, and API-backed literature monitoring.

affaan-m/scholar-evaluation

Structured scholarly-work evaluation for papers, proposals, literature reviews, methods sections, evidence quality, citation support, and research-writing feedback.

affaan-m/uspto-database

USPTO patent and trademark data workflow for official record lookup, PatentSearch queries, TSDR checks, assignment data, and reproducible IP research logs.

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.

Habilidades Relacionadas