Communitygithub.com

vite-patterns

Vite-Build-Tool-Patterns: Konfiguration, Plugins, HMR, Umgebungsvariablen, Proxy-Setup, SSR, Library-Modus, Abhängigkeits-Pre-Bündelung und Build-Optimierung. Aktivieren bei Arbeit mit vite.config.ts, Vite-Plugins oder Vite-basierten Projekten.

Was ist vite-patterns?

Dieses Skill bietet umfassende Pattern und Best Practices für die Arbeit mit Vite 8+ (sowie abwärtskompatibel für Vite 5–7). Es deckt die gesamte Palette der Vite-Entwicklung ab: von der Konfiguration der `vite.config.ts` über die Verwendung von Umgebungsvariablen, das Einrichten des Dev-Server-Proxys, die Optimierung des Build-Outputs (Chunks, Minifizierung, Assets) bis hin zum Publizieren von Bibliotheken im Library-Modus. Der Skill erklärt die grundlegende Funktionsweise von Vite (Dev-Modus mit nativem ESM, Build-Modus mit Rolldown oder Rollup, Abhängigkeits-Pre-Bündelung mit esbuild) und gibt klare Anleitungen zu wichtigen Themen wie HMR, benutzerdefinierten Plugins, Sicherheit (Umgang mit VITE_-Präfix), SSR-Externalisierung und der Vermeidung häufiger Fallstricke (z. B. Unterschiede zwischen Dev und Build, veraltete Chunks nach Deployment, Docker/Container-Konfiguration). Es ist für alle gängigen Vite-Plattformen wie Cursor, Codex und Claude Code geeignet und hilft Entwicklern, typische Fehler zu vermeiden und die Produktivität zu steigern.

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

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Was macht vite-patterns?

Build-Tool- und Dev-Server-Patterns für Vite 8+-Projekte. Behandelt Konfiguration, Umgebungsvariablen, Proxy-Setup, Library-Modus, Abhängigkeits-Pre-Bündelung und häufige Produktionsfallstricke.

Verwendung

  • Konfigurieren von vite.config.ts oder vite.config.js
  • Einrichten von Umgebungsvariablen oder .env-Dateien
  • Konfigurieren des Dev-Server-Proxys für API-Backends
  • Optimieren des Build-Outputs (Chunks, Minifizierung, Assets)
  • Publizieren von Bibliotheken mit build.lib
  • Fehlersuche bei Abhängigkeits-Pre-Bündelung oder CJS/ESM-Interop
  • Debuggen von HMR, Dev-Server oder Build-Fehlern
  • Auswählen oder Anordnen von Vite-Plugins

Funktionsweise

  • Dev-Modus liefert Quelldateien als natives ESM – ohne Bündelung. Transformationen erfolgen bei Bedarf pro Modulanfrage, daher sind Kaltstarts schnell und HMR präzise.
  • Build-Modus verwendet Rolldown (v7+) oder Rollup (v5–v6), um die App für die Produktion zu bündeln, mit Tree-Shaking, Code-Splitting und Oxc-basierter Minifizierung.
  • Abhängigkeits-Pre-Bündelung konvertiert CJS/UMD-Abhängigkeiten einmalig über esbuild zu ESM und speichert das Ergebnis unter node_modules/.vite, sodass nachfolgende Starts diesen Schritt überspringen.
  • Plugins teilen eine einheitliche Schnittstelle für Dev und Build – dasselbe Plugin-Objekt funktioniert sowohl für die bedarfsgesteuerten Transformationen des Dev-Servers als auch für die Produktions-Pipeline.
  • Umgebungsvariablen werden zur Build-Zeit statisch inline eingefügt. VITE_-präfixierte Variablen werden zu öffentlichen Konstanten im Bundle; alles ohne Präfix ist für Client-Code unsichtbar.

Beispiele

Konfigurationsstruktur

Basis-Konfiguration

// 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 },
  },
})

Bedingte Konfiguration

// 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())   // nur VITE_-Präfix (sicher)

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

Wichtige Konfigurationsoptionen

SchlüsselStandardBeschreibung
root'.'Projektwurzel (wo index.html liegt)
base'/'Öffentlicher Basispfad für bereitgestellte Assets
envPrefix'VITE_'Präfix für client-seitige Umgebungsvariablen
build.outDir'dist'Ausgabeverzeichnis
build.minify'oxc'Minifizierer ('oxc', 'terser' oder false)
build.sourcemapfalsetrue, 'inline' oder 'hidden'

Plugins

Essentielle Plugins

Die meisten Plugin-Anforderungen werden von einigen wenigen gut gewarteten Paketen abgedeckt. Greifen Sie zu diesen, bevor Sie eigene Plugins schreiben.

PluginZweckVerwendung
@vitejs/plugin-react-swcReact HMR + Fast Refresh über SWCStandard für React-Apps (schneller als Babel-Variante)
@vitejs/plugin-reactReact HMR + Fast Refresh über BabelNur wenn Sie Babel-Plugins benötigen (Emotion, MobX-Dekorateure)
@vitejs/plugin-vueVue 3 SFC-UnterstützungVue-Apps
vite-plugin-checkerFührt tsc + ESLint in einem Worker-Thread mit HMR-Overlay ausJede TypeScript-App – Vite führt KEINE Typprüfung während vite build durch
vite-tsconfig-pathsBerücksichtigt tsconfig.json paths-AliaseImmer wenn Sie bereits Aliase in tsconfig.json haben
vite-plugin-dtsErzeugt .d.ts-Dateien im Library-ModusBeim Publizieren von TypeScript-Bibliotheken
vite-plugin-svgrImportiert SVGs als React-KomponentenReact-Apps, die SVGs als Komponenten verwenden
rollup-plugin-visualizerBundle-Treemap/Sunburst-BerichtRegelmäßige Bundle-Größenüberprüfungen (mit enforce: 'post' verwenden)
vite-plugin-pwaZero-Config PWA + WorkboxOffline-fähige Apps

Wichtiger Hinweis: vite build transpiliert, führt aber KEINE Typprüfung durch. Typfehler gelangen stillschweigend in die Produktion, wenn Sie nicht vite-plugin-checker hinzufügen oder tsc --noEmit in CI ausführen.

Eigene Plugins erstellen

Das Erstellen eigener Plugins ist selten – die meisten Anforderungen werden durch vorhandene Plugins abgedeckt. Wenn Sie dennoch eines benötigen, beginnen Sie inline in vite.config.ts und extrahieren Sie es nur bei Wiederverwendung.

// vite.config.ts – minimales Inline-Plugin
function myPlugin(): Plugin {
  return {
    name: 'my-plugin',                       // erforderlich, muss eindeutig sein
    enforce: 'pre',                           // 'pre' | 'post' (optional)
    apply: 'build',                           // 'build' | 'serve' (optional)
    transform(code, id) {
      if (!id.endsWith('.custom')) return
      return { code: transformCustom(code), map: null }
    },
  }
}

Wichtige Hooks: transform (Quelle ändern), resolveId + load (virtuelle Module), transformIndexHtml (in HTML einfügen), configureServer (Dev-Middleware hinzufügen), hotUpdate (benutzerdefinierte HMR – ersetzt das veraltete handleHotUpdate in v7+).

Virtuelle Module verwenden die \0-Präfix-Konvention – resolveId gibt '\0virtual:my-id' zurück, sodass andere Plugins es überspringen. Benutzercode importiert 'virtual:my-id'.

Für die vollständige Plugin-API siehe vite.dev/guide/api-plugin. Verwenden Sie während der Entwicklung vite-plugin-inspect, um die Transformations-Pipeline zu debuggen.

HMR-API

Framework-Plugins (@vitejs/plugin-react, @vitejs/plugin-vue usw.) behandeln HMR automatisch. Greifen Sie nur dann direkt auf import.meta.hot zu, wenn Sie benutzerdefinierte Zustandsspeicher, Entwicklerwerkzeuge oder framework-agnostische Dienstprogramme erstellen, die den Zustand über Aktualisierungen hinweg beibehalten müssen.

// src/store.ts – manuelle HMR für ein Vanilla-Modul
if (import.meta.hot) {
  // Zustand über Aktualisierungen hinweg beibehalten (muss MUTIEREN, .data niemals neu zuweisen)
  import.meta.hot.data.count = import.meta.hot.data.count ?? 0

  // Nebenwirkungen bereinigen, bevor das Modul ersetzt wird
  import.meta.hot.dispose((data) => clearInterval(data.intervalId))

  // Eigene Aktualisierungen dieses Moduls akzeptieren
  import.meta.hot.accept()
}

Der gesamte import.meta.hot-Code wird aus Produktions-Builds herausgetree-shaked – keine Guard-Entfernung erforderlich.

Umgebungsvariablen

Vite lädt .env, .env.local, .env.[mode] und .env.[mode].local in dieser Reihenfolge (spätere überschreiben frühere); *.local-Dateien sind in gitignore und für lokale Geheimnisse gedacht.

Client-seitiger Zugriff

Nur VITE_-präfixierte Variablen werden dem Client-Code ausgesetzt:

import.meta.env.VITE_API_URL   // string
import.meta.env.MODE            // 'development' | 'production' | benutzerdefiniert
import.meta.env.BASE_URL        // base-Konfigurationswert
import.meta.env.DEV             // boolean
import.meta.env.PROD            // boolean
import.meta.env.SSR             // boolean

Verwendung von Env in der Konfiguration

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

export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd())          // nur VITE_-Präfix (sicher)
  return {
    define: {
      __API_URL__: JSON.stringify(env.VITE_API_URL),
    },
  }
})

Sicherheit

VITE_-Präfix ist KEINE Sicherheitsgrenze

Jede Variable mit dem Präfix VITE_ wird zur Build-Zeit statisch in das Client-Bundle eingefügt. Minifizierung, Base64-Kodierung und das Deaktivieren von Sourcemaps verbergen sie NICHT. Ein entschlossener Angreifer kann jede VITE_-Variable aus dem ausgelieferten JavaScript extrahieren.

Regel: Nur öffentliche Werte (API-URLs, Feature-Flags, öffentliche Schlüssel) gehören in VITE_-Variablen. Geheimnisse (API-Tokens, Datenbank-URLs, private Schlüssel) MÜSSEN serverseitig hinter einer API oder Serverless-Funktion leben.

Die loadEnv('')-Falle

// SCHLECHT: Übergabe von '' als drittes Argument lädt ALLE Umgebungsvariablen – einschließlich Server-Geheimnisse –
// und macht sie verfügbar, um über `define` in Client-Code eingefügt zu werden.
const env = loadEnv(mode, process.cwd(), '')

// GUT: Explizite Präfix-Liste
const env = loadEnv(mode, process.cwd(), ['VITE_', 'APP_'])

Sourcemaps in der Produktion

Produktions-Sourcemaps leaken Ihren ursprünglichen Quellcode. Deaktivieren Sie sie, es sei denn, Sie laden sie in einen Fehler-Tracker (Sentry, Bugsnag) hoch und löschen sie anschließend lokal:

build: {
  sourcemap: false,                                  // Standard – so belassen
}

.gitignore-Checkliste

  • .env.local, .env.*.local – lokale Geheimnis-Überschreibungen
  • dist/ – Build-Ausgabe
  • node_modules/.vite – Pre-Bundle-Cache (veraltete Einträge verursachen Phantomfehler)

Server-Proxy

// vite.config.ts – server.proxy
server: {
  proxy: {
    '/foo': 'http://localhost:4567',                    // String-Kurzform

    '/api': {
      target: 'http://localhost:8080',
      changeOrigin: true,                               // erforderlich für virtuelle Host-Backends
      rewrite: (path) => path.replace(/^\/api/, ''),
    },
  },
}

Für WebSocket-Proxying fügen Sie ws: true zur Routenkonfiguration hinzu.

Build-Optimierung

Manuelle Chunks

// vite.config.ts – build.rolldownOptions
build: {
  rolldownOptions: {
    output: {
      // Objektform: Bestimmte Pakete gruppieren
      manualChunks: {
        'react-vendor': ['react', 'react-dom'],
        'ui-vendor': ['@radix-ui/react-dialog', '@radix-ui/react-popover'],
      },
    },
  },
}
// Funktionsform: Nach Heuristik aufteilen
manualChunks(id) {
  if (id.includes('node_modules/react')) return 'react-vendor'
  if (id.includes('node_modules')) return 'vendor'
}

Leistung

Barrel-Dateien vermeiden

Barrel-Dateien (index.ts, die alles aus einem Verzeichnis re-exportieren) zwingen Vite, jede re-exportierte Datei zu laden, selbst wenn Sie ein einzelnes Symbol importieren. Dies ist die #1-Verlangsamung des Dev-Servers, die in den offiziellen Dokumenten genannt wird.

// SCHLECHT – das Importieren eines Dienstprogramms zwingt Vite, das gesamte Barrel zu laden
import { slash } from '@/utils'

// GUT – Direkter Import, nur die eine Datei wird geladen
import { slash } from '@/utils/slash'

Explizite Import-Erweiterungen verwenden

Jede implizite Erweiterung erzwingt bis zu 6 Dateisystemprüfungen über resolve.extensions. In großen Codebasen summiert sich das.

// SCHLECHT
import Component from './Component'

// GUT
import Component from './Component.tsx'

Verengen Sie tsconfig.json allowImportingTsExtensions + resolve.extensions auf nur die Erweiterungen, die Sie tatsächlich verwenden.

Hot-Path-Routen aufwärmen

server.warmup.clientFiles transformiert bekannte Hot-Einträge vor, bevor der Browser sie anfordert – dies eliminiert den Cold-Load-Anforderungswasserfall bei großen Apps.

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

Langsame Dev-Server profilieren

Wenn vite dev sich langsam anfühlt, starten Sie mit vite --profile, interagieren Sie mit der App und drücken Sie dann p+Eingabe, um eine .cpuprofile-Datei zu speichern. Laden Sie sie in Speedscope, um herauszufinden, welche Plugins Zeit fressen – normalerweise die buildStart-, config- oder configResolved-Hooks in Community-Plugins.

Library-Modus

Wenn Sie ein npm-Paket veröffentlichen, verwenden Sie build.lib. Zwei Fallstricke sind wichtiger als die Konfigurationsdetails:

  1. Typen werden nicht ausgegeben – fügen Sie vite-plugin-dts hinzu oder führen Sie tsc --emitDeclarationOnly separat aus.
  2. Peer-Abhängigkeiten MÜSSEN externalisiert werden – nicht aufgeführte Peers werden in Ihre Bibliothek gebündelt, was bei Verwendern doppelte Laufzeitfehler verursacht.
// 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'],  // jede Peer-Abhängigkeit
  },
}

SSR-Externalisierung

Bare createServer({ middlewareMode: true })-Setups sind Framework-Autoren-Territorium. Die meisten Apps sollten stattdessen Nuxt, Remix, SvelteKit, Astro oder TanStack Start verwenden. Was Sie als Framework-Benutzer anpassen werden, ist die Externalisierungskonfiguration, wenn Abhängigkeiten in SSR brechen:

// vite.config.ts – ssr-Optionen
ssr: {
  external: ['node-native-package'],           // als require() im SSR-Bundle beibehalten
  noExternal: ['esm-only-package'],            // in SSR-Output erzwingen (behebt die meisten SSR-Fehler)
  target: 'node',                              // 'node' oder 'webworker'
}

Abhängigkeits-Pre-Bündelung

Vite bündelt Abhängigkeiten vor, um CJS/UMD in ESM zu konvertieren und die Anzahl der Anfragen zu reduzieren.

// vite.config.ts – optimizeDeps
optimizeDeps: {
  include: [
    'lodash-es',                              // bekannte schwere Abhängigkeiten vor-bündeln
    'cjs-package',                            // CJS-Abhängigkeiten, die Interop-Probleme verursachen
    'deep-lib/components/**',                 // Glob für tiefe Importe
  ],
  exclude: ['local-esm-package'],             // muss gültiges ESM sein, wenn ausgeschlossen
  force: true,                                // Cache ignorieren, neu optimieren (temporäres Debuggen)
}

Häufige Fallstricke

Dev stimmt nicht mit Build überein

Dev verwendet esbuild/Rolldown für Transformationen; Build verwendet Rolldown für die Bündelung. CJS-Bibliotheken können sich zwischen beiden unterschiedlich verhalten. Überprüfen Sie immer mit vite build && vite preview, bevor Sie bereitstellen.

Veraltete Chunks nach Deployment

Neue Builds erzeugen neue Chunk-Hashes. Benutzer mit aktiven Sitzungen fordern alte Dateinamen an, die nicht mehr existieren. Vite hat keine integrierte Lösung. Minderungsmaßnahmen:

  • Behalten Sie alte dist/assets/-Dateien für ein Deployment-Fenster live
  • Fangen Sie dynamische Importfehler in Ihrem Router ab und erzwingen Sie ein erneutes Laden der Seite

Docker und Container

Vite bindet standardmäßig an localhost, was von außerhalb eines Containers nicht erreichbar ist:

// vite.config.ts – Docker/Container-Setup
server: {
  host: true,                                  // bind 0.0.0.0
  hmr: { clientPort: 3000 },                   // wenn hinter einem Reverse-Proxy
}

Monorepo-Dateizugriff

Vite beschränkt die Dateiauslieferung auf das Projektstammverzeichnis. Pakete außerhalb des Stammverzeichnisses werden blockiert:

// vite.config.ts – Monorepo-Dateizugriff
server: {
  fs: {
    allow: ['..'],                             // übergeordnetes Verzeichnis zulassen (Workspace-Root)
  },
}

Anti-Patterns

// SCHLECHT: Setzen von envPrefix auf '' legt ALLE Umgebungsvariablen (einschließlich Geheimnisse) offen
envPrefix: ''

// SCHLECHT: Annahme, dass require() in Vite funktioniert (es funktioniert nicht nativ; verwenden Sie Importe)
// (Anmerkung: require() wird in modernem Vite nicht unterstützt; verwenden Sie ESM-Importe)

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.

Verwandte Skills