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 Funktionenactivateund optionaldeactivate. Inactivateregistrieren 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
- Gerüst erzeugen:
npx --package yo --package generator-code -- yo codefragt Typ, Name und Sprache ab und legt ein Projekt an. - Mit F5 starten Sie ein zweites VS-Code-Fenster, den Extension Development Host, in dem Ihre Extension geladen ist. Haltepunkte im Quellcode funktionieren direkt.
- Für automatisierte Tests stellt Microsoft Hilfspakete bereit, die eine Testinstanz von VS Code herunterladen und Ihre Tests darin ausführen.
- Vor der Veröffentlichung packen Sie die Extension mit
vsce packagein 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.
Anleitungen zu VS Code & IDEs
- Extension erstellen
Mit yo code zum lauffähigen Gerüst: welche Vorlagen es gibt, was in package.json und extension.ts steht, wie Sie einen eigenen Befehl bauen und im Extension Development Host testen.
- Extension veröffentlichen
Publisher-Konto, Zugriffstoken, Pflichtfelder in package.json, vsce package und vsce publish, Vorabversionen, Automatisierung und die zusätzliche Veröffentlichung auf Open VSX.
- Language Server Protocol
Ein Server, viele Editoren: wie das Language Server Protocol Sprachfunktionen vom Editor trennt, welche Nachrichten ausgetauscht werden und wann sich ein eigener Server lohnt.
- JetBrains-Plugin entwickeln
Wie Sie ein Plugin für IntelliJ IDEA, PyCharm oder WebStorm mit Gradle und Kotlin aufsetzen, Actions und Services registrieren und im JetBrains Marketplace veröffentlichen.
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.
Weiterlesen
- Grundlagen
Sprachen, Schnittstellen, Build-Werkzeuge, Versionskontrolle und Tests: das Handwerkszeug, das für Erweiterungen jeder Plattform gebraucht wird.
- Veröffentlichen
Stores und Prüfprozesse, Versionsnummern und Changelog, Lizenzen und Bezahlmodelle: was nach dem letzten Commit kommt und warum ein Add-on nie ganz fertig ist.
- Glossar
Von Add-on bis WebExtensions: die wichtigsten Fachbegriffe der Plugin-Entwicklung in kurzen, plattformübergreifenden Erklärungen.