Back

Comment créer et utiliser des plugins dans Vite

Comment créer et utiliser des plugins dans Vite

La création de plugins Vite personnalisés vous permet d’étendre votre processus de build au-delà de la configuration par défaut — que vous ayez besoin de transformer des types de fichiers personnalisés, d’injecter une logique au moment du build ou d’ajouter des middlewares au serveur de développement. Si vous avez atteint les limites de la configuration standard de Vite, créer votre propre plugin est la prochaine étape naturelle.

Ce guide couvre les concepts essentiels : le fonctionnement de l’API Plugin de Vite, les hooks de cycle de vie clés que vous utiliserez, et des exemples pratiques pour vous lancer. Vous apprendrez à créer, tester et publier des plugins qui résolvent des problèmes concrets dans votre flux de travail de développement.

Points clés à retenir

  • Les plugins Vite étendent les processus de développement et de build de production via des hooks de cycle de vie
  • La plupart des plugins Rollup fonctionnent dans Vite, mais les fonctionnalités du serveur de développement nécessitent des hooks spécifiques à Vite
  • Commencez par des transformations simples avant de passer à des patterns avancés comme les modules virtuels
  • Suivez les conventions de nommage et les standards de documentation lors de la publication de plugins

Comprendre les plugins Vite et leur relation avec Rollup

Les plugins Vite sont des objets JavaScript qui s’intègrent à différentes étapes du processus de développement et de build. Ils sont construits sur le système de plugins de Rollup, avec des hooks supplémentaires spécifiques au serveur de développement de Vite.

Vite utilise deux outils de build différents en interne : esbuild alimente le serveur de développement ultra-rapide avec des modules ES natifs, tandis que Rollup gère le bundling de production pour un résultat optimal. Cette architecture duale signifie que vos plugins peuvent cibler des environnements spécifiques en utilisant l’option apply :

function myPlugin(): Plugin {
  return {
    name: 'my-plugin',
    apply: 'serve', // Only runs during development
    // ... hooks
  }
}

La plupart des plugins Rollup fonctionnent dans Vite sans modification. Cependant, si vous avez besoin de fonctionnalités du serveur de développement — comme ajouter des middlewares ou modifier le HTML pendant le développement — vous aurez besoin de hooks spécifiques à Vite.

Structure de base et configuration d’un plugin

Chaque plugin Vite doit avoir une propriété name et au moins une fonction hook :

import type { Plugin } from 'vite'

function myPlugin(options?: MyPluginOptions): Plugin {
  return {
    name: 'vite-plugin-example',
    enforce: 'pre', // Optional: control plugin ordering
    apply: 'build', // Optional: 'serve' | 'build' | undefined
    
    // Hook functions go here
    transform(code, id) {
      if (id.endsWith('.custom')) {
        return transformCustomFile(code)
      }
    }
  }
}

L’API Plugin fournit des définitions TypeScript pour tous les hooks et options. Importez le type Plugin depuis ‘vite’ pour bénéficier d’une sécurité de type complète et de l’autocomplétion.

Hooks de cycle de vie essentiels dans l’API Plugin

Différents hooks se déclenchent à différentes étapes du processus de build. Voici les plus couramment utilisés :

Hooks de configuration

  • config : Modifie la configuration Vite avant sa résolution
  • configResolved : Accède à la configuration finale résolue

Hooks de transformation

  • transform : Modifie le code source de modules individuels
  • load : Logique de chargement personnalisée pour des types de fichiers spécifiques
  • resolveId : Résolution de modules personnalisée
{
  name: 'transform-plugin',
  transform(code, id) {
    if (!id.includes('node_modules') && id.endsWith('.js')) {
      return {
        code: addCustomHeader(code),
        map: null // Source map support
      }
    }
  }
}

Hooks de serveur et de build

  • configureServer : Ajoute des middlewares personnalisés au serveur de développement
  • transformIndexHtml : Modifie les fichiers HTML
  • writeBundle : S’exécute après l’écriture du bundle sur le disque

Chaque hook a des types de retour et un timing d’exécution spécifiques. Le hook transform s’exécute pour chaque module, alors gardez-le rapide. Utilisez load pour les opérations coûteuses sur des fichiers spécifiques.

Créer votre premier plugin Vite : exemples pratiques

Créons trois plugins pratiques qui démontrent des patterns courants :

Exemple 1 : Modification HTML

function htmlPlugin(): Plugin {
  return {
    name: 'html-modifier',
    transformIndexHtml(html) {
      return html.replace(
        '</head>',
        '<script>console.log("Injected!")</script></head>'
      )
    }
  }
}

Exemple 2 : Middleware du serveur de développement

function analyticsPlugin(): Plugin {
  return {
    name: 'request-analytics',
    configureServer(server) {
      server.middlewares.use((req, res, next) => {
        console.log(`${req.method} ${req.url}`)
        next()
      })
    }
  }
}

Exemple 3 : Génération de fichiers au moment du build

import path from 'path'
import fs from 'fs'
import type { Plugin, ResolvedConfig } from 'vite'

function generateManifest(): Plugin {
  let config: ResolvedConfig
  
  return {
    name: 'generate-manifest',
    configResolved(resolvedConfig) {
      config = resolvedConfig
    },
    writeBundle() {
      const manifestPath = path.join(config.build.outDir, 'manifest.json')
      fs.writeFileSync(manifestPath, JSON.stringify({
        timestamp: Date.now(),
        version: process.env.npm_package_version
      }))
    }
  }
}

Pour le débogage, utilisez console.log dans vos hooks pour tracer l’exécution. Les méthodes this.warn() et this.error() fournissent un meilleur rapport d’erreurs que de lever des exceptions.

Patterns avancés et bonnes pratiques pour les plugins

Modules virtuels

Créez des modules qui n’existent pas sur le disque :

const virtualModuleId = 'virtual:my-module'
const resolvedVirtualModuleId = '\0' + virtualModuleId

export function virtualPlugin(): Plugin {
  return {
    name: 'virtual-plugin',
    resolveId(id) {
      if (id === virtualModuleId) {
        return resolvedVirtualModuleId
      }
    },
    load(id) {
      if (id === resolvedVirtualModuleId) {
        return `export const msg = "from virtual module"`
      }
    }
  }
}

Optimisation des performances

Mettez en cache les transformations coûteuses :

const cache = new Map<string, string>()

function cachedTransform(): Plugin {
  return {
    name: 'cached-transform',
    transform(code, id) {
      if (cache.has(id)) return cache.get(id)
      
      const result = expensiveOperation(code)
      cache.set(id, result)
      return result
    }
  }
}

Testez vos plugins Vite en utilisant Vitest avec l’API createServer pour vérifier le comportement des hooks de manière isolée.

Publier et partager votre plugin

Suivez ces conventions lors de la publication :

  1. Nommez votre package vite-plugin-[nom]
  2. Incluez "vite-plugin" dans les mots-clés du package.json
  3. Documentez pourquoi il est spécifique à Vite (si vous utilisez des hooks exclusifs à Vite)
  4. Ajoutez des préfixes de framework si spécifique à un framework : vite-plugin-vue-[nom]

Créez un README clair avec des instructions d’installation, des exemples de configuration et une documentation de l’API. Soumettez votre plugin à awesome-vite pour atteindre la communauté.

Conclusion

La création de plugins Vite personnalisés vous donne un contrôle total sur votre processus de build. Commencez par des transformations simples en utilisant des hooks comme transform ou transformIndexHtml, puis étendez vers des patterns plus complexes selon vos besoins. L’API Plugin est puissante mais accessible — la plupart des plugins ne nécessitent que quelques hooks pour résoudre des problèmes spécifiques.

Pour une exploration plus approfondie, consultez la documentation officielle des plugins Vite et étudiez les plugins populaires de l’écosystème. Votre prochaine optimisation de build ou amélioration de flux de travail n’est peut-être qu’à un plugin de distance.

FAQ

Oui, la plupart des plugins Rollup fonctionnent avec Vite sans modification. Cependant, les plugins qui dépendent du hook moduleParsed ou qui nécessitent des fonctionnalités du serveur de développement requièrent des adaptations spécifiques à Vite. Consultez la documentation du plugin pour les notes de compatibilité avec Vite.

Utilisez des instructions console.log dans vos hooks pour tracer le flux d'exécution. Les méthodes this.warn() et this.error() fournissent un meilleur rapport d'erreurs. Vous pouvez également utiliser la variable d'environnement DEBUG avec Vite pour voir des logs détaillés.

L'option enforce contrôle l'ordre d'exécution des plugins. Les plugins pre s'exécutent avant les plugins core de Vite, les plugins post s'exécutent après. Utilisez pre pour les transformations d'entrée et post pour les modifications de sortie. Sans enforce, les plugins s'exécutent dans l'ordre où ils apparaissent.

Envisagez de publier si votre plugin résout un problème que d'autres pourraient rencontrer, même s'il est spécialisé. Documentez clairement son cas d'usage spécifique. Pour les plugins vraiment spécifiques à un projet, gardez-les locaux ou dans un registre privé à la place.

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay