Communitygithub.com

vite-patterns

Patrons de configuration et optimisation du build pour Vite, incluant plugins, HMR, variables d'environnement, proxy, SSR, mode librairie, pré-regroupement des dépendances et performance.

Qu'est-ce que vite-patterns ?

Ce skill fournit un guide complet des bonnes pratiques et configurations avancées pour les projets utilisant Vite (version 8+). Il couvre la configuration de `vite.config.ts`, la gestion des variables d'environnement (avec les pièges de sécurité liés au préfixe `VITE_`), la configuration du proxy serveur, l'optimisation du build (découpage manuel, minification, sourcemaps), le mode librairie (`build.lib`), ainsi que le pré-regroupement des dépendances (`optimizeDeps`). Il explique également le fonctionnement interne de Vite (mode dev sans bundling, mode build avec Rolldown/Rollup, HMR) et propose des optimisations de performances comme l'évitement des fichiers barils (`index.ts`), l'utilisation explicite des extensions de fichiers, et le préchauffage des routes (`server.warmup`). Le skill est utile pour les développeurs qui travaillent avec `vite.config.ts`, les plugins Vite, ou des projets basés sur Vite. Il met en garde contre les pièges courants (différence dev/build, chunks obsolètes, accès fichiers monorepo) et les anti-patrons (exposition de secrets via les variables d'environnement). Les exemples de code sont fournis en TypeScript, avec des instructions pour les conteneurs Docker et les projets monorepo.

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

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Patrons Vite

Patrons d'outils de build et de serveur de développement pour les projets Vite 8+. Couvre la configuration, les variables d'environnement, la configuration du proxy, le mode librairie, le pré-regroupement des dépendances et les pièges de production courants.

Quand utiliser

  • Configurer vite.config.ts ou vite.config.js
  • Mettre en place des variables d'environnement ou des fichiers .env
  • Configurer le proxy du serveur de développement pour les backends API
  • Optimiser la sortie du build (chunks, minification, ressources)
  • Publier des librairies avec build.lib
  • Résoudre les problèmes de pré-regroupement des dépendances ou d'interopérabilité CJS/ESM
  • Déboguer les erreurs HMR, de serveur de développement ou de build
  • Choisir ou ordonner les plugins Vite

Comment ça fonctionne

  • Le mode dev sert les fichiers sources en tant qu'ESM natif — sans regroupement. Les transformations ont lieu à la demande pour chaque requête de module, ce qui explique les démarrages à froid rapides et le HMR précis.
  • Le mode build utilise Rolldown (v7+) ou Rollup (v5–v6) pour regrouper l'application pour la production avec élagage, division de code et minification basée sur Oxc.
  • Le pré-regroupement des dépendances convertit les dépendances CJS/UMD en ESM une fois via esbuild et met en cache le résultat sous node_modules/.vite, de sorte que les démarrages suivants évitent ce travail.
  • Les plugins partagent une interface unifiée entre le dev et le build — le même objet plugin fonctionne à la fois pour les transformations à la demande du serveur de développement et pour le pipeline de production.
  • Les variables d'environnement sont injectées statiquement au moment du build. Les variables préfixées par VITE_ deviennent des constantes publiques dans le bundle ; tout ce qui n'est pas préfixé est invisible pour le code client.

Exemples

Structure de configuration

Configuration de base

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

Configuration conditionnelle

// 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())   // préfixé par VITE_ uniquement (sûr)

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

Options de configuration clés

CléDéfautDescription
root'.'Racine du projet (où se trouve index.html)
base'/'Chemin de base public pour les ressources déployées
envPrefix'VITE_'Préfixe pour les variables d'environnement exposées au client
build.outDir'dist'Répertoire de sortie
build.minify'oxc'Minificateur ('oxc', 'terser' ou false)
build.sourcemapfalsetrue, 'inline' ou 'hidden'

Plugins

Plugins essentiels

La plupart des besoins en plugins sont couverts par une poignée de packages bien maintenus. Utilisez-les avant d'écrire les vôtres.

PluginObjectifQuand utiliser
@vitejs/plugin-react-swcReact HMR + Fast Refresh via SWCPar défaut pour les applis React (plus rapide que la variante Babel)
@vitejs/plugin-reactReact HMR + Fast Refresh via BabelSeulement si vous avez besoin de plugins Babel (emotion, décorateurs MobX)
@vitejs/plugin-vueSupport Vue 3 SFCApplis Vue
vite-plugin-checkerExécute tsc + ESLint dans un thread worker avec superposition HMRToute appli TypeScript — Vite ne fait PAS de vérification de type pendant vite build
vite-tsconfig-pathsRespecte les alias de chemins tsconfig.jsonQuand vous avez déjà des alias dans tsconfig.json
vite-plugin-dtsÉmet des fichiers .d.ts en mode librairiePublication de librairies TypeScript
vite-plugin-svgrImporte les SVG en tant que composants ReactApplis React utilisant des SVG comme composants
rollup-plugin-visualizerRapport treemap/sunburst du bundleAudits périodiques de la taille du bundle (utiliser enforce: 'post')
vite-plugin-pwaPWA sans configuration + WorkboxApplis fonctionnant hors ligne

Avertissement critique : vite build transpile mais ne fait PAS de vérification de type. Les erreurs de type sont déployées en production silencieusement, sauf si vous ajoutez vite-plugin-checker ou exécutez tsc --noEmit dans le CI.

Créer des plugins personnalisés

La création est rare — la plupart des besoins sont couverts par des plugins existants. Quand vous en avez besoin, commencez en ligne dans vite.config.ts et extrayez seulement si réutilisé.

// vite.config.ts — plugin en ligne minimal
function monPlugin(): Plugin {
  return {
    name: 'mon-plugin',                       // obligatoire, doit être unique
    enforce: 'pre',                           // 'pre' | 'post' (optionnel)
    apply: 'build',                           // 'build' | 'serve' (optionnel)
    transform(code, id) {
      if (!id.endsWith('.custom')) return
      return { code: transformCustom(code), map: null }
    },
  }
}

Hooks clés : transform (modifier la source), resolveId + load (modules virtuels), transformIndexHtml (injecter dans le HTML), configureServer (ajouter un middleware de dev), hotUpdate (HMR personnalisé — remplace handleHotUpdate déprécié dans v7+).

Modules virtuels utilisent la convention de préfixe \0 — resolveId retourne '\0virtual:mon-id' pour que les autres plugins l'ignorent. Le code utilisateur importe 'virtual:mon-id'.

Pour l'API complète des plugins, voir vite.dev/guide/api-plugin. Utilisez vite-plugin-inspect pendant le développement pour déboguer le pipeline de transformation.

API HMR

Les plugins de framework (@vitejs/plugin-react, @vitejs/plugin-vue, etc.) gèrent le HMR automatiquement. Utilisez import.meta.hot directement uniquement lors de la création de stores d'état personnalisés, d'outils de développement ou d'utilitaires agnostiques au framework qui doivent persister l'état entre les mises à jour.

// src/store.ts — HMR manuel pour un module vanilla
if (import.meta.hot) {
  // Persister l'état entre les mises à jour (doit MUTER, ne jamais réaffecter .data)
  import.meta.hot.data.count = import.meta.hot.data.count ?? 0

  // Nettoyer les effets de bord avant que le module ne soit remplacé
  import.meta.hot.dispose((data) => clearInterval(data.intervalId))

  // Accepter les mises à jour de ce module lui-même
  import.meta.hot.accept()
}

Tout le code import.meta.hot est élagué des builds de production — aucun retrait de garde nécessaire.

Variables d'environnement

Vite charge .env, .env.local, .env.[mode] et .env.[mode].local dans cet ordre (les derniers écrasent les précédents) ; les fichiers *.local sont ignorés par git et destinés aux secrets locaux.

Accès côté client

Seules les variables préfixées par VITE_ sont exposées au code client :

import.meta.env.VITE_API_URL   // chaîne
import.meta.env.MODE            // 'development' | 'production' | personnalisé
import.meta.env.BASE_URL        // valeur de la config base
import.meta.env.DEV             // booléen
import.meta.env.PROD            // booléen
import.meta.env.SSR             // booléen

Utiliser les variables d'env dans la config

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

export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd())          // préfixé par VITE_ uniquement (sûr)
  return {
    define: {
      __API_URL__: JSON.stringify(env.VITE_API_URL),
    },
  }
})

Sécurité

Le préfixe VITE_ n'est PAS une frontière de sécurité

Toute variable préfixée par VITE_ est injectée statiquement dans le bundle client au moment du build. La minification, l'encodage base64 et la désactivation des sourcemaps ne la cachent PAS. Un attaquant déterminé peut extraire n'importe quelle variable VITE_ du JavaScript livré.

Règle : Seules les valeurs publiques (URLs d'API, indicateurs de fonctionnalités, clés publiques) vont dans les variables VITE_. Les secrets (jetons d'API, URLs de base de données, clés privées) DOIVENT vivre côté serveur derrière une API ou une fonction sans serveur.

Le piège de loadEnv('')

// MAUVAIS : passer '' comme troisième argument charge TOUTES les variables d'env — y compris les secrets serveur —
// et les rend disponibles pour être injectées dans le code client via `define`.
const env = loadEnv(mode, process.cwd(), '')

// BON : liste explicite des préfixes
const env = loadEnv(mode, process.cwd(), ['VITE_', 'APP_'])

Sourcemaps en production

Les sourcemaps de production divulguent votre code source original. Désactivez-les sauf si vous les téléversez vers un traqueur d'erreurs (Sentry, Bugsnag) et les supprimez localement ensuite :

build: {
  sourcemap: false,                                  // défaut — gardez-le ainsi
}

Checklist .gitignore

  • .env.local, .env.*.local — écrasements de secrets locaux
  • dist/ — sortie du build
  • node_modules/.vite — cache de pré-regroupement (les entrées obsolètes causent des erreurs fantômes)

Proxy serveur

// vite.config.ts — server.proxy
server: {
  proxy: {
    '/foo': 'http://localhost:4567',                    // raccourci chaîne

    '/api': {
      target: 'http://localhost:8080',
      changeOrigin: true,                               // nécessaire pour les backends à hébergement virtuel
      rewrite: (path) => path.replace(/^\/api/, ''),
    },
  },
}

Pour le proxy WebSocket, ajoutez ws: true à la configuration de la route.

Optimisation du build

Chunks manuels

// vite.config.ts — build.rolldownOptions
build: {
  rolldownOptions: {
    output: {
      // Forme objet : grouper des packages spécifiques
      manualChunks: {
        'react-vendor': ['react', 'react-dom'],
        'ui-vendor': ['@radix-ui/react-dialog', '@radix-ui/react-popover'],
      },
    },
  },
}
// Forme fonction : diviser par heuristique
manualChunks(id) {
  if (id.includes('node_modules/react')) return 'react-vendor'
  if (id.includes('node_modules')) return 'vendor'
}

Performance

Éviter les fichiers barils

Les fichiers barils (index.ts réexportant tout d'un répertoire) forcent Vite à charger chaque fichier réexporté même lorsque vous importez un seul symbole. C'est le #1 des ralentissements du serveur de développement signalé par la documentation officielle.

// MAUVAIS — importer un utilitaire force Vite à charger tout le baril
import { slash } from '@/utils'

// BON — import direct, seul le fichier est chargé
import { slash } from '@/utils/slash'

Être explicite avec les extensions d'import

Chaque extension implicite force jusqu'à 6 vérifications du système de fichiers via resolve.extensions. Dans les grandes bases de code, cela s'additionne.

// MAUVAIS
import Component from './Component'

// BON
import Component from './Component.tsx'

Réduisez tsconfig.json allowImportingTsExtensions + resolve.extensions aux seules extensions que vous utilisez réellement.

Préchauffer les routes à fort trafic

server.warmup.clientFiles pré-transforme les entrées connues avant que le navigateur ne les demande — éliminant la cascade de requêtes de chargement à froid sur les grandes applications.

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

Profilage des serveurs de développement lents

Quand vite dev semble lent, commencez par vite --profile, interagissez avec l'application, puis appuyez sur p+entrée pour enregistrer un .cpuprofile. Chargez-le dans Speedscope pour trouver quels plugins consomment du temps — généralement les hooks buildStart, config ou configResolved dans les plugins communautaires.

Mode librairie

Lors de la publication d'un package npm, utilisez build.lib. Deux pièges sont plus importants que le détail de la configuration :

  1. Les types ne sont pas émis — ajoutez vite-plugin-dts ou exécutez tsc --emitDeclarationOnly séparément.
  2. Les dépendances de pair DOIVENT être externalisées — les pairs non listés sont regroupés dans votre librairie, provoquant des erreurs de double runtime chez les consommateurs.
// vite.config.ts
build: {
  lib: {
    entry: 'src/index.ts',
    formats: ['es', 'cjs'],
    fileName: (format) => `ma-lib.${format}.js`,
  },
  rolldownOptions: {
    external: ['react', 'react-dom', 'react/jsx-runtime'],  // chaque dépendance de pair
  },
}

Externalisations SSR

Les configurations createServer({ middlewareMode: true }) nues sont du ressort des auteurs de framework. La plupart des applications devraient utiliser Nuxt, Remix, SvelteKit, Astro ou TanStack Start à la place. Ce que vous ajusterez en tant qu'utilisateur de framework, c'est la configuration des externalisations lorsque des dépendances cassent en SSR :

// vite.config.ts — options ssr
ssr: {
  external: ['package-natif-node'],           // garder en tant que require() dans le bundle SSR
  noExternal: ['package-uniquement-esm'],     // forcer le regroupement dans la sortie SSR (corrige la plupart des erreurs SSR)
  target: 'node',                              // 'node' ou 'webworker'
}

Pré-regroupement des dépendances

Vite pré-regroupe les dépendances pour convertir CJS/UMD en ESM et réduire le nombre de requêtes.

// vite.config.ts — optimizeDeps
optimizeDeps: {
  include: [
    'lodash-es',                              // forcer le pré-regroupement des dépendances lourdes connues
    'package-cjs',                            // dépendances CJS qui causent des problèmes d'interopérabilité
    'lib-profonde/composants/**',                 // glob pour les imports profonds
  ],
  exclude: ['package-esm-local'],             // doit être un ESM valide si exclu
  force: true,                                // ignorer le cache, ré-optimiser (débogage temporaire)
}

Pièges courants

Le dev ne correspond pas au build

Le dev utilise esbuild/Rolldown pour les transformations ; le build utilise Rolldown pour le regroupement. Les librairies CJS peuvent se comporter différemment entre les deux. Vérifiez toujours avec vite build && vite preview avant de déployer.

Chunks obsolètes après le déploiement

Les nouveaux builds produisent de nouveaux hachages de chunks. Les utilisateurs avec des sessions actives demandent des noms de fichiers anciens qui n'existent plus. Vite n'a pas de solution intégrée. Atténuations :

  • Gardez les anciens fichiers dist/assets/ actifs pendant une fenêtre de déploiement
  • Attrapez les erreurs d'import dynamique dans votre routeur et forcez un rechargement de page

Docker et conteneurs

Vite se lie à localhost par défaut, ce qui est inaccessible depuis l'extérieur d'un conteneur :

// vite.config.ts — configuration Docker/conteneur
server: {
  host: true,                                  // lier 0.0.0.0
  hmr: { clientPort: 3000 },                   // si derrière un proxy inverse
}

Accès aux fichiers dans les monorepos

Vite restreint le service de fichiers à la racine du projet. Les packages en dehors de la racine sont bloqués :

// vite.config.ts — accès aux fichiers monorepo
server: {
  fs: {
    allow: ['..'],                             // autoriser le répertoire parent (racine de l'espace de travail)
  },
}

Anti-patrons

// MAUVAIS : Définir envPrefix à '' expose TOUTES les variables d'environnement (y compris les secrets) au client
envPrefix: ''

// MAUVAIS : Supposer que require() fonctionne dans ...

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.

Skills associés