~/vscode-extensions/

VS-Code-Extensions und IDE-Plugins entwickeln

Wie Erweiterungen für Visual Studio Code aufgebaut sind, warum das Language Server Protocol Editoren verbindet und wie Plugins für JetBrains-IDEs entstehen.

Code-Editoren und IDEs sind selbst Werkzeuge für Entwickler und deshalb besonders offen für Erweiterungen. Visual Studio Code hat sich nicht zuletzt wegen seines Erweiterungsökosystems durchgesetzt: Sprachunterstützung, Linter, Themes, Git-Werkzeuge und KI-Assistenten kommen fast alle als Extension. Wer seinen eigenen Arbeitsalltag automatisieren möchte, findet hier einen dankbaren Einstieg, denn die erste Extension ist in einer Stunde geschrieben.

Wie VS Code Erweiterungen lädt

VS Code basiert auf Electron und führt Extensions in einem eigenen Prozess aus, dem Extension Host. Das schützt die Oberfläche: Hängt eine Extension, bleibt der Editor bedienbar. Extensions greifen nicht direkt auf die Oberfläche zu, sondern ausschließlich über die Extension API, die im Modul vscode bereitsteht.

Zwei Dateien bilden den Kern:

  • package.json ist das Manifest. Neben Name, Version und Herausgeber steht hier unter contributes, was die Extension beisteuert: Befehle, Menüeinträge, Tastenkürzel, Einstellungen, Sprachen, Themes oder Ansichten in der Seitenleiste. Diese Contribution Points wertet VS Code aus, ohne Code der Extension auszuführen.
  • extension.ts (oder .js) exportiert die Funktionen activate und optional deactivate. In activate registrieren Sie die Implementierungen für die deklarierten Befehle.
{
  "name": "zeilen-zaehler",
  "displayName": "Zeilen zählen",
  "version": "0.1.0",
  "publisher": "ihr-publisher-name",
  "engines": { "vscode": "^1.90.0" },
  "main": "./out/extension.js",
  "contributes": {
    "commands": [
      { "command": "zeilenZaehler.zaehlen", "title": "Zeilen der Auswahl zählen" }
    ]
  }
}
import * as vscode from "vscode";

export function activate(context: vscode.ExtensionContext) {
  const befehl = vscode.commands.registerCommand("zeilenZaehler.zaehlen", () => {
    const editor = vscode.window.activeTextEditor;
    if (!editor) return;
    const auswahl = editor.selection;
    const zeilen = auswahl.end.line - auswahl.start.line + 1;
    vscode.window.showInformationMessage(`Ausgewählt: ${zeilen} Zeilen`);
  });
  context.subscriptions.push(befehl);
}

Alles, was Sie registrieren, kommt in context.subscriptions. So räumt VS Code beim Deaktivieren automatisch auf.

Aktivierung: nur laden, wenn nötig

Extensions werden nicht beim Start geladen, sondern erst, wenn ein Aktivierungsereignis eintritt: Jemand ruft einen Befehl auf, öffnet eine Datei einer bestimmten Sprache oder einen Ordner mit einer bestimmten Datei. Neuere VS-Code-Versionen leiten viele dieser Ereignisse automatisch aus den Contribution Points ab. Vermeiden Sie das Ereignis *, das die Extension sofort beim Start lädt. Es verlangsamt den Editor für alle, auch wenn die Extension gerade gar nicht gebraucht wird.

Entwickeln, testen, debuggen

  1. Gerüst erzeugen: npx --package yo --package generator-code -- yo code fragt Typ, Name und Sprache ab und legt ein Projekt an.
  2. Mit F5 starten Sie ein zweites VS-Code-Fenster, den Extension Development Host, in dem Ihre Extension geladen ist. Haltepunkte im Quellcode funktionieren direkt.
  3. Für automatisierte Tests stellt Microsoft Hilfspakete bereit, die eine Testinstanz von VS Code herunterladen und Ihre Tests darin ausführen.
  4. Vor der Veröffentlichung packen Sie die Extension mit vsce package in eine .vsix-Datei und installieren sie testweise von Hand.

Webviews und eigene Oberflächen

Reichen Befehle, Statusleiste und Baumansichten nicht aus, kann eine Extension eine Webview öffnen: ein eingebettetes Fenster mit eigenem HTML, CSS und JavaScript. Webviews sind flexibel, aber aufwendig. Sie kommunizieren nur über Nachrichten mit der Extension, brauchen eine eigene Content Security Policy und sollten sich an die Farbvariablen des aktiven Themes halten, damit sie in hellen und dunklen Themes gut aussehen.

Language Server Protocol

Früher musste jede Sprache für jeden Editor einzeln unterstützt werden. Das Language Server Protocol, von Microsoft veröffentlicht und heute von vielen Editoren genutzt, trennt beides: Ein Language Server berechnet Vervollständigungen, Diagnosen, Definitionen und Umbenennungen; der Editor zeigt sie nur an. Die Kommunikation läuft über JSON-RPC. Ein einmal geschriebener Server funktioniert damit in VS Code, Neovim, Emacs, Sublime Text und anderen Editoren mit LSP-Unterstützung.

Plugins für JetBrains-IDEs

IntelliJ IDEA, PyCharm, WebStorm und die übrigen JetBrains-IDEs teilen sich die IntelliJ Platform. Plugins dafür schreiben Sie in Kotlin oder Java und bauen sie mit Gradle und dem offiziellen IntelliJ-Platform-Gradle-Plugin. Das Manifest heißt hier plugin.xml, die Andockstellen heißen Extension Points. Anders als bei VS Code laufen JetBrains-Plugins im selben Prozess wie die IDE und haben dadurch tieferen Zugriff, etwa auf den Syntaxbaum des Codes (PSI). Das macht sie mächtiger, verlangt aber mehr Sorgfalt bei Performance und Threading. Ein Gradle-Task startet eine Test-IDE mit Ihrem Plugin, veröffentlicht wird im JetBrains Marketplace.

VS Code JetBrains-IDEs
Sprache TypeScript, JavaScript Kotlin, Java
Manifest package.json plugin.xml
Ausführung eigener Extension-Host-Prozess im IDE-Prozess
Testlauf F5, Extension Development Host Gradle-Task startet Test-IDE
Store Visual Studio Marketplace, Open VSX JetBrains Marketplace

Veröffentlichen

Für den Visual Studio Marketplace brauchen Sie einen Publisher und ein Zugriffstoken; das Werkzeug vsce übernimmt Packen und Hochladen. Für Open VSX gibt es mit ovsx ein vergleichbares Werkzeug. Achten Sie auf ein aussagekräftiges README.md, ein Symbol und eine CHANGELOG.md, denn diese Dateien bilden die Detailseite im Store. Mehr dazu im Bereich Add-ons veröffentlichen und pflegen.

faq

Fragen und Antworten

Brauche ich TypeScript für VS-Code-Extensions?
Nein, reines JavaScript funktioniert auch. TypeScript ist aber üblich, weil die gesamte Extension API typisiert ist und der Editor dadurch beim Schreiben fast jede Methode samt Parametern vorschlägt. Der offizielle Generator bietet beide Varianten an.
Laufen VS-Code-Extensions auch in VSCodium oder Cursor?
Meist ja, denn diese Editoren basieren auf demselben Quellcode. Sie beziehen Erweiterungen aber häufig nicht aus dem Visual Studio Marketplace, sondern aus der offenen Registry Open VSX. Wer alle erreichen will, veröffentlicht in beiden.
Was ist der Unterschied zwischen einer Extension und einem Language Server?
Die Extension ist das Paket, das VS Code lädt. Ein Language Server ist ein eigenständiger Prozess, der Sprachfunktionen wie Autovervollständigung oder Fehlerprüfung berechnet. Die Extension startet ihn und vermittelt zwischen Editor und Server über das Language Server Protocol.