Back

So erstellen und verwenden Sie Plugins in Vite

So erstellen und verwenden Sie Plugins in Vite

Das Erstellen benutzerdefinierter Vite-Plugins ermöglicht es Ihnen, Ihren Build-Prozess über die Standardkonfiguration hinaus zu erweitern – egal ob Sie benutzerdefinierte Dateitypen transformieren, Build-Zeit-Logik injizieren oder Development-Server-Middleware hinzufügen müssen. Wenn Sie an die Grenzen der Standard-Vite-Konfiguration gestoßen sind, ist die Erstellung eines eigenen Plugins der natürliche nächste Schritt.

Dieser Leitfaden behandelt die wesentlichen Konzepte: wie die Plugin-API von Vite funktioniert, die wichtigsten Lifecycle-Hooks, die Sie verwenden werden, und praktische Beispiele für den Einstieg. Sie lernen, Plugins zu erstellen, zu testen und zu veröffentlichen, die reale Probleme in Ihrem Entwicklungs-Workflow lösen.

Wichtigste Erkenntnisse

  • Vite-Plugins erweitern sowohl Entwicklungs- als auch Produktions-Build-Prozesse durch Lifecycle-Hooks
  • Die meisten Rollup-Plugins funktionieren in Vite, aber Dev-Server-Features erfordern Vite-spezifische Hooks
  • Beginnen Sie mit einfachen Transformationen, bevor Sie zu fortgeschrittenen Mustern wie virtuellen Modulen übergehen
  • Befolgen Sie Namenskonventionen und Dokumentationsstandards bei der Veröffentlichung von Plugins

Vite-Plugins verstehen und ihre Beziehung zu Rollup

Vite-Plugins sind JavaScript-Objekte, die sich in verschiedene Phasen des Entwicklungs- und Build-Prozesses einklinken. Sie basieren auf dem Plugin-System von Rollup, mit zusätzlichen Hooks, die spezifisch für den Development-Server von Vite sind.

Vite verwendet intern zwei verschiedene Build-Tools: esbuild betreibt den blitzschnellen Development-Server mit nativen ES-Modulen, während Rollup das Production-Bundling für optimale Ausgabe übernimmt. Diese duale Architektur bedeutet, dass Ihre Plugins mit der apply-Option auf bestimmte Umgebungen abzielen können:

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

Die meisten Rollup-Plugins funktionieren in Vite ohne Modifikation. Wenn Sie jedoch Dev-Server-Funktionalität benötigen – wie das Hinzufügen von Middleware oder das Modifizieren von HTML während der Entwicklung – benötigen Sie Vite-spezifische Hooks.

Grundlegende Plugin-Struktur und Konfiguration

Jedes Vite-Plugin muss eine name-Eigenschaft und mindestens eine Hook-Funktion haben:

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

Die Plugin-API bietet TypeScript-Definitionen für alle Hooks und Optionen. Importieren Sie den Plugin-Typ aus ‘vite’ für vollständige Typsicherheit und Autovervollständigung.

Wesentliche Lifecycle-Hooks in der Plugin-API

Verschiedene Hooks werden in unterschiedlichen Phasen des Build-Prozesses ausgelöst. Hier sind die am häufigsten verwendeten:

Konfigurations-Hooks

  • config: Vite-Konfiguration modifizieren, bevor sie aufgelöst wird
  • configResolved: Auf die endgültig aufgelöste Konfiguration zugreifen

Transform-Hooks

  • transform: Quellcode einzelner Module modifizieren
  • load: Benutzerdefinierte Ladelogik für bestimmte Dateitypen
  • resolveId: Benutzerdefinierte Modulauflösung
{
  name: 'transform-plugin',
  transform(code, id) {
    if (!id.includes('node_modules') && id.endsWith('.js')) {
      return {
        code: addCustomHeader(code),
        map: null // Source map support
      }
    }
  }
}

Server- und Build-Hooks

  • configureServer: Benutzerdefinierte Middleware zum Dev-Server hinzufügen
  • transformIndexHtml: HTML-Dateien modifizieren
  • writeBundle: Nach dem Schreiben des Bundles auf die Festplatte ausführen

Jeder Hook hat spezifische Rückgabetypen und Ausführungszeitpunkte. Der transform-Hook wird für jedes Modul ausgeführt, halten Sie ihn also schnell. Verwenden Sie load für aufwändige Operationen auf bestimmten Dateien.

Ihr erstes Vite-Plugin erstellen: Praktische Beispiele

Lassen Sie uns drei praktische Plugins erstellen, die gängige Muster demonstrieren:

Beispiel 1: HTML-Modifikation

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

Beispiel 2: Dev-Server-Middleware

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

Beispiel 3: Build-Zeit-Dateigenerierung

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

Verwenden Sie zum Debuggen console.log in Ihren Hooks, um die Ausführung nachzuverfolgen. Die Methoden this.warn() und this.error() bieten bessere Fehlerberichterstattung als das Werfen von Exceptions.

Fortgeschrittene Plugin-Muster und Best Practices

Virtuelle Module

Erstellen Sie Module, die nicht auf der Festplatte existieren:

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"`
      }
    }
  }
}

Performance-Optimierung

Cachen Sie aufwändige Transformationen:

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

Testen Sie Ihre Vite-Plugins mit Vitest unter Verwendung der createServer-API, um das Hook-Verhalten isoliert zu überprüfen.

Ihr Plugin veröffentlichen und teilen

Befolgen Sie diese Konventionen bei der Veröffentlichung:

  1. Benennen Sie Ihr Paket vite-plugin-[name]
  2. Fügen Sie "vite-plugin" in die package.json-Keywords ein
  3. Dokumentieren Sie, warum es Vite-spezifisch ist (falls Vite-only-Hooks verwendet werden)
  4. Fügen Sie Framework-Präfixe hinzu, wenn framework-spezifisch: vite-plugin-vue-[name]

Erstellen Sie eine klare README mit Installationsanweisungen, Konfigurationsbeispielen und API-Dokumentation. Reichen Sie Ihr Plugin bei awesome-vite ein, um die Community zu erreichen.

Fazit

Das Erstellen benutzerdefinierter Vite-Plugins gibt Ihnen vollständige Kontrolle über Ihren Build-Prozess. Beginnen Sie mit einfachen Transformationen unter Verwendung von Hooks wie transform oder transformIndexHtml und erweitern Sie dann bei Bedarf zu komplexeren Mustern. Die Plugin-API ist leistungsstark und dennoch zugänglich – die meisten Plugins benötigen nur wenige Hooks, um spezifische Probleme zu lösen.

Für eine tiefere Erkundung lesen Sie die offizielle Vite-Plugin-Dokumentation und studieren Sie beliebte Plugins im Ökosystem. Ihre nächste Build-Optimierung oder Workflow-Verbesserung könnte nur ein Plugin entfernt sein.

Häufig gestellte Fragen

Ja, die meisten Rollup-Plugins funktionieren mit Vite ohne Modifikation. Allerdings erfordern Plugins, die auf dem moduleParsed-Hook basieren oder Dev-Server-Funktionalität benötigen, Vite-spezifische Anpassungen. Prüfen Sie die Plugin-Dokumentation auf Hinweise zur Vite-Kompatibilität.

Verwenden Sie console.log-Anweisungen in Ihren Hooks, um den Ausführungsfluss nachzuverfolgen. Die Methoden this.warn() und this.error() bieten bessere Fehlerberichterstattung. Sie können auch die DEBUG-Umgebungsvariable mit Vite verwenden, um detaillierte Logs zu sehen.

Die enforce-Option steuert die Ausführungsreihenfolge von Plugins. Pre-Plugins werden vor den Vite-Core-Plugins ausgeführt, Post-Plugins danach. Verwenden Sie pre für Input-Transformationen und post für Output-Modifikationen. Ohne enforce werden Plugins in der Reihenfolge ausgeführt, in der sie erscheinen.

Erwägen Sie eine Veröffentlichung, wenn Ihr Plugin ein Problem löst, mit dem auch andere konfrontiert sein könnten, selbst wenn es spezialisiert ist. Dokumentieren Sie seinen spezifischen Anwendungsfall klar. Für wirklich projektspezifische Plugins behalten Sie diese besser lokal oder in einer privaten Registry.

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