zurück zum Artikel

Visual Studio Code, Teil 3: Eigene Erweiterungen implementieren

Dr. Fabian Deitelhoff

(Bild: r.classen/Shutterstock.com)

Teil 3 der Serie erklÀrt, was zum Erstellen eigener Erweiterungen notwendig ist und welche Möglichkeiten auch bei speziellen Anforderungen offen stehen.

Das Konzept von Visual Studio Code ist die Erweiterbarkeit. Neben vorgefertigten Erweiterungen, die Nutzerinnen und Nutzer nur installieren mĂŒssen, lassen sich auch selbst erstellte Erweiterungen als Plug-ins implementieren. Die zwei bisherigen Teile der Serie haben gezeigt, dass Visual Studio Code ein vielseitiger Editor ist. UrsprĂŒnglich als reine UnterstĂŒtzung bei der Webentwicklung gedacht, leistet Visual Studio Code heutzutage deutlich mehr. Einen Großteil seiner Funktionsvielfalt und FlexibilitĂ€t verdankt der Editor den Erweiterungen. Teil 2 der Artikelserie hat gezeigt, wie der Extension Manager und der Extension-Marktplatz sich nutzen lassen [1], um Erweiterungen zu finden [2], zu installieren und zu verwalten – fĂŒr vorhandene funktioniert das problemlos.

Visual Studio Code – dreiteilige Serie

Wenn fĂŒr eine spezielle Anforderung keine Erweiterung existiert, lassen sich neue Extensions fĂŒr Visual Studio Code schreiben. Teil 3 erklĂ€rt nun abschließend, was fĂŒr das Erstellen eigener Erweiterungen notwendig ist und welchen Spielraum sie eröffnen. Im Mittelpunkt stehen dabei das Spektrum der Extensions, ihre Implementierung und Veröffentlichung sowie das Fallbeispiel der Language Server, wenn umfassende Anpassungen an der UnterstĂŒtzung von Programmiersprachen in Visual Studio geplant sind.

Visual Studio Code bietet eine ganze Palette an Optionen, wie sich die Entwicklungsumgebung sinnvoll erweitern lÀsst. Beim Erstellen einer neuen Erweiterung ist es nicht immer leicht, den konkreten Contribution Point oder die passende API zu finden. Unter einem Contribution Point ist eine JSON-Deklaration [6] zu verstehen, die eine Visual-Studio-Code-Erweiterung in der package.json vornehmen muss, um anzuzeigen, dass der betreffende Bereich von VS Code erweitert wird.

Die package.json muss fĂŒr jede Erweiterung vorliegen und heißt daher Extension Manifest [7]. Darin sind unter anderem Informationen wie der Name und die Versionsnummer der Erweiterung sowie die unterstĂŒtzten Versionen von VS Code aufgefĂŒhrt, zudem die verwendete Lizenz. Über die Contribution Points kann sich eine Erweiterung in die Breakpoints, Kommandos, Debugger oder unterstĂŒtzten Programmiersprachen einklinken. Die VS-Code-API ist ein Satz an JavaScript-APIs, die sich in einer eigenen Erweiterung fĂŒr VS Code aufrufen lassen [8] – beispielsweise, um einen neuen Befehl zu registrieren. Eine Übersicht aller VS-Code-APIs hĂ€lt die Dokumentation bereit.

Diese beiden technischen Ankerpunkte sind zentral fĂŒr die Erweiterungen in VS Code. Mit ihrer Hilfe ist es möglich, Befehle, Konfigurationen oder TastaturkĂŒrzel zu registrieren. Auch das Speichern von Daten im Workspace, das Anzeigen von Benachrichtigungen oder das Aufrufen von Auswahldialogen sind klassische Aufgaben einer Erweiterung. Deren Designelemente wie die Farben von User Interface (UI), Syntaxhervorhebung oder die eingesetzten Datei-Icons lassen sich ebenfalls anpassen.

Bei den Sprachfunktionen ist zwischen deklarativen und programmatischen Features zu unterscheiden. Beide gehören zur Kategorie der Language Extensions, die UnterstĂŒtzung fĂŒr das Editieren von Programmiersprachen und Dialekten in VS Code bieten. Die Sprachfunktionen lassen sich deklarativ erstellen. Dazu gibt es sprachspezifische Konfigurationsdateien, die jeweils eine Sprache oder einen Dialekt wie etwa HTML, CSS und TypeScript abdecken. Diese Form der Erweiterungen hat Zugriff auf die Syntaxhervorhebung, die VervollstĂ€ndigung von Snippets, das Matching von Klammern und die automatische EinrĂŒckung von Code (Indentation). Die programmatischen Sprachfunktionen gehen einen Schritt weiter und ermöglichen Funktionen wie das AutovervollstĂ€ndigen, das PrĂŒfen auf Fehler und die Möglichkeit, zu einer Deklaration zu springen. Oft werden diese Funktionen von Language Servern bereitgestellt.

Sie sind komplexer in der Implementierung, bieten aber auch breitere Einsatzoptionen. Ein Language Server, der das Language Server Protocol nutzt [9], ist im Falle von VS Code ein eigens implementiertes Analyse-Tool, das in einem separaten Prozess lĂ€uft. Das Tool ist zudem hĂ€ufig in der nativen Programmiersprache implementiert, wozu der Language Server Dienste bereitstellt. Ein Language Server, der VS Code die UnterstĂŒtzung von PHP beibringt, mit Funktionen wie AutovervollstĂ€ndigung, Diagnosefunktionen und Formatierungen, ist beispielsweise schon in der Programmiersprache enthalten.

DarĂŒber hinaus lĂ€sst sich die Workbench in VS Code erweitern [10], also das ĂŒbergeordnete User Interface der Entwicklungsumgebung – Beispiele dafĂŒr sind die Titelleiste, die Seitenleiste oder Informationen in der Statusleiste. Auf diese Weise lassen sich neue KontextmenĂŒs und -aktionen integrieren, ebenso wie das Rendern zusĂ€tzlicher Inhalte ĂŒber die WebView API. Sogenannte Debugger Extensions erlauben es zudem, sich in das Debugging-UI und dessen FunktionalitĂ€t einzuklinken [11]. Die Erweiterungen fĂŒr das Debugging gehören zu den umfangreichsten Anpassungen. Wenn es nicht direkt ein eigener Debugger sein muss, bietet die VS-Code-API einen Satz von Aufrufen, um Funktionen auf der Basis des vorhandenen VS-Code-Debuggers zu implementieren. Damit sind unter anderem Automatisierungen realisierbar.

ZunĂ€chst ist eine installierte Version von VS Code erforderlich. SpĂ€testens fĂŒr den Test der eigenen Erweiterungen ist die Anwendung essenziell. Node.js und npm beziehungsweise yarn stehen ebenfalls auf der Liste notwendiger Voraussetzungen. VS Code arbeitet bei Erweiterungen mit einem Template, das sich einfach installieren lĂ€sst. Damit wird der Einstieg in die Entwicklung von Erweiterungen nach Erfahrung des Autors zum Kinderspiel. Als Generator ist Yeoman im Einsatz, ein Open-Source-Scaffolding-Tool zum Erstellen von Projektvorlagen. Der Generator fĂŒr VS Code heißt "vscode-generator-code". Über yarn lĂ€sst er sich wie folgt installieren:

yarn global add yo generator-code

Anschließend reicht es aus, den Befehl yo code in dem Verzeichnis auszufĂŒhren, das die neue Vorlage fĂŒr die Extension aufnehmen soll. Eine BegrĂŒĂŸung wie in Abbildung 1 weist darauf hin, dass es sich um den Generator fĂŒr Visual-Studio-Code-Erweiterungen handelt, und sie bietet direkt weitere Optionen an. Eine Erweiterung lĂ€sst sich mit TypeScript oder JavaScript implementieren. ZusĂ€tzlich ist beispielsweise die Auswahl eines Color Theme, Code Snippets, Language Packs oder ein Notebook Renderer vorhanden.

BegrĂŒĂŸungsbildschirm von Yeoman mit den Auswahlmöglichkeiten fĂŒr VS-Code-Erweiterungen (Abb. 1)

Eine Erweiterung mit TypeScript dient an dieser Stelle als erstes Beispiel. Nach der Auswahl der gewĂŒnschten Vorlage fragt der Generator ein paar typische Informationen wie den Namen der Erweiterung, die Beschreibung und den zukĂŒnftig zu nutzenden Paketmanager ab. Danach erstellt er die notwendigen Dateien und Verzeichnisse und stĂ¶ĂŸt den ausgewĂ€hlten Paketmanager an, um die AbhĂ€ngigkeiten aufzulösen und zu installieren.

Das erzeugte Projekt lĂ€sst sich in VS Code öffnen. Die Entwicklungsumgebung erstellt Standarddateien und einige Tests als Vorlage, die sich anschließend weiterverarbeiten lassen. Das Projekt ist so eingerichtet, dass es sich direkt ausfĂŒhren und debuggen lĂ€sst. In VS Code genĂŒgt es, einmal F5 zu drĂŒcken, um den Code zu kompilieren und in eine neue VS-Code-Instanz einzubinden. Dieser sogenannte Extension Development Host, den Abbildung 2 darstellt, lĂ€dt die neue Erweiterung. Im Beispiel stellt die Erweiterung einen Befehl namens "Hello World" zur VerfĂŒgung. Beim AusfĂŒhren erscheint rechts unten eine kleine Benachrichtigung. Die Hallo-Welt-Erweiterung funktioniert und lĂ€sst sich nun weiterentwickeln sowie debuggen.

Das Beispielkommando in der Hallo-Welt-Erweiterung fĂŒr VS Code (Abb. 2)

Eine Erweiterung besteht aus zahlreichen Dateien, die das Scaffolding-Template fĂŒr Erweiterungen erstellt. Im Verzeichnis src existiert die Datei extension.ts, die den primĂ€ren Code enthĂ€lt. Dort importiert das Modul "vscode" die VS Code Extensibility API und implementiert die beiden grundlegenden Methoden activate und deactivate. Sie sind dafĂŒr zustĂ€ndig, die Erweiterung zu starten beziehungsweise anzuhalten. In der activate-Methode ist auch der gesamte Code enthalten, der fĂŒr das vorherige Hallo-Welt-Beispiel notwendig war.

Im nĂ€chsten Beispiel geht es um das Feature der CodeLens. Damit lassen sich zusĂ€tzliche Informationen ĂŒber Codestellen im Editor einblenden, und das ist mittlerweile eine beliebte Funktion, um Daten aus einer Versionsverwaltung anzuzeigen oder Informationen zur Nutzung einer Methode aufzurufen. Ein eigener CodeLens-Provider muss dafĂŒr registriert sein:

const codelensProvider = new CodelensProvider();
languages.registerCodeLensProvider("*", codelensProvider);

Der erste Parameter der Methode zum Registrieren gibt den Dokumententyp an. In diesem Beispiel steht die Wildcard fĂŒr alle Typen, um den Provider ausprobieren zu können. Der neue CodeLens-Provider implementiert die Schnittstelle vscode.CodeLensProvider, die wichtige Rahmenbedingungen vorgibt, wie die Methoden provideCodeLenses und resolveCodeLens. Die erste Methode erstellt eine Liste von CodeLenses fĂŒr das Dokument, in dem das Kommando aufgerufen wurde.

Im besten Fall ist sie so schnell wie möglich, um alle CodeLenses anzuzeigen. Dauert die Berechnung lĂ€nger, sollte der implementierende Code ĂŒber den range-Parameter nur die CodeLenses fĂŒr den sichtbaren Bereich zurĂŒckgeben und die resolveCodeLens-Methode implementieren. FĂŒr jede sichtbare CodeLens gilt es, sie aufzurufen, was beispielsweise beim Scrollen der Fall ist.

Durch diesen Code ist es möglich, den CodeLens-Befehl auszufĂŒhren, um die Beispiel-CodeLens zu aktivieren. DafĂŒr existieren die Befehle Enable CodeLens und Disable CodeLens. Abbildung 3 zeigt das Ergebnis nach dem AusfĂŒhren des Enable-Befehls. Da unser Beispielprovider fĂŒr alle Typen von Dokumenten funktioniert, reicht eine Textdatei mit einigen Zeilen Code aus, um fĂŒr jede dieser Zeilen eine CodeLens darzustellen. Sie sind zudem interaktiv und lassen sich anklicken, um weitere Informationen in einer Benachrichtigung anzuzeigen. Auch Argumente lassen sich so ĂŒbermitteln, um Daten in den Benachrichtigungen zu nutzen.

CodeLens-Beispiele aus der Demo-Erweiterung fĂŒr VS Code (Abb. 3)

Eine Erweiterung fĂŒr VS Code zu schreiben, ist nur die halbe Miete. Entwicklerinnen und Entwickler mĂŒssen sie zudem testen und veröffentlichen, damit andere sie nutzen können. Der Veröffentlichungsprozess lĂ€uft ĂŒber den Marketplace fĂŒr VS-Code-Erweiterungen oder alternativ als Paket im VSIX-Format, das sich mit anderen teilen lĂ€sst. Besonders einfach funktioniert es ĂŒber das Kommandozeilenwerkzeug "Visual Studio Code Extensions", kurz vsce, das sich ĂŒber npm beziehungsweise yarn installieren lĂ€sst.

Nach der Installation reicht es, in das Verzeichnis mit der Erweiterung zu wechseln und die folgenden Befehle auszufĂŒhren:

vsce package
vsce publish

Bei der Veröffentlichung gilt es, einige EinschrĂ€nkungen und Hinweise zu beachten. Aus SicherheitsgrĂŒnden sind beispielsweise keine benutzerdefinierten SVG-Dateien erlaubt. Sie dĂŒrfen weder als Icons noch als Badges in der package.json hinterlegt sein. Auch die Bild-URLs in den Dateien README.md und CHANGELOG.md dĂŒrfen nicht auf SVG-Dateien verweisen. Da Azure DevOps fĂŒr den Marketplace genutzt wird, laufen die Verwaltung und die Authentifizierung ebenfalls darĂŒber. Damit der Veröffentlichungsvorgang funktioniert, ist ein Access Token ĂŒber Azure DevOps notwendig. Dazu ist zunĂ€chst ein Organisationskonto bei Azure DevOps erforderlich, das wiederum ein persönliches Microsoft-Konto, ein GitHub-Konto, ein Arbeits- oder Schulkonto voraussetzt. Wichtig ist, dass das Konto dafĂŒr geeignet ist, bei Azure DevOps eine Organisation zu erstellen, falls das eigene Unternehmen dort noch nicht registriert war.

Das Anlegen einer Organisation ist ebenso wie Azure DevOps zunĂ€chst kostenfrei, wenn es sich um kleinere Projekte oder den Open-Source-Bereich handelt. DarĂŒber ist das Token generierbar. Die Kosten aller weiteren Optionen sind bei Azure einsehbar. Anschließend ist ein sogenannter Publisher notwendig, der sich ĂŒber die Verwaltung des Marketplace erstellen lĂ€sst. Über den Befehl vsce login <publisher name> lĂ€sst sich der Log-in testen.

Funktioniert alles, steht der Veröffentlichung der Erweiterung nichts mehr im Weg. Wer nur ein Paket erstellen möchte, um die Erweiterung zunĂ€chst lokal nach einer regulĂ€ren Installation zu testen, kann das mit dem oben erwĂ€hnten package-Befehl von vsce erledigen. Die so erzeugte VSIX-Datei lĂ€sst sich anschließend installieren.

Das Tool vsce kann aber noch mehr. So kann es unter anderem nach Erweiterungen suchen, Metadaten ermitteln und Erweiterungen wieder aus dem Marketplace entfernen. Eine Liste aller Möglichkeiten lĂ€sst sich ĂŒber vsce --help anzeigen.

Damit die eigene Erweiterung gut im Marketplace prĂ€sentiert wird, sollten alle Metadaten ordnungsgemĂ€ĂŸ vorhanden sein. Dazu gehören eine ordentliche README.md-Datei sowie eine sauber ausgefĂŒllte package.json mit Anzeigenamen, Beschreibung, Version, Lizenz, Homepage und Repository. Relevant sind auch die Kategorien, die aus einer vorgegebenen Liste auszuwĂ€hlen sind, damit Nutzer ĂŒber diese Informationen die von ihnen gesuchten Erweiterungen schneller und zuverlĂ€ssiger finden. Generell ist eine gute PrĂ€sentation im Marketplace wichtig, auch wenn nach Wahrnehmung des Autors die meisten Erweiterungen wohl ĂŒber direkte Empfehlungen gefunden und installiert werden.

Die bisher im Artikel beschriebenen Möglichkeiten bieten bereits einigen Spielraum, um VS Code an die eigenen BedĂŒrfnisse anzupassen. Daneben gibt es weitere Themen, mit denen komplexe Erweiterungen umsetzbar sind, die man im Hinterkopf behalten sollte.

Dazu gehört beispielsweise der Extension Host. Diese Komponente ist in VS Code fĂŒr das Laden, Deaktivieren und die generelle Verwaltung von Erweiterungen zustĂ€ndig. Der Host sorgt dafĂŒr, dass die Performance von VS Code nicht durch Erweiterungen beeinflusst wird oder dass etwa das User Interface auf unerlaubte Weise verĂ€ndert wird. Der Host ist auch dafĂŒr zustĂ€ndig, Erweiterungen verzögert beziehungsweise erst bei Bedarf zu laden.

Ein erweitertes Thema ist die UnterstĂŒtzung der Remote-Entwicklung und GitHub Codespaces [12]. Über das Feature "Visual Studio Code Remote Development" lĂ€sst sich mit Sourcecode interagieren, der auf einer entfernten Maschine liegt. DafĂŒr ist auf der lokalen Maschine die Installation von VS Code mit UI Extensions notwendig. Die Kommunikation ĂŒbernimmt der lokale Extension Host. Auf dem Server ist ein VS Code Server mit Workspace Extensions und einem Remote Extension Host notwendig. Die VS-Code-APIs sind direkt so umgesetzt, dass bei einem Aufruf automatisch die korrekte Maschine adressiert wird, was die Entwicklung der eigenen Erweiterung in diesem Bereich vereinfacht.

Wer plant, eine Erweiterung fĂŒr kĂŒnftige Versionen von VS Code zu entwickeln, sollte einen Blick auf das sogenannte Proposed API werfen. Damit sind die geplanten Anpassungen gemeint, die der API bevorstehen. Um die Neuerungen zu nutzen, ist ein Insider-Release von Visual Studio Code erforderlich. ZusĂ€tzlich dazu ist die Einstellung "enableProposedApi": true in der package.json der eigenen Erweiterung zu setzen. Zu guter Letzt wird die Datei vscode.proposed.d.ts benötigt, in der sich die Anpassungen der API befinden. Die Datei lĂ€sst sich ĂŒber das vscode-dts-CLI ins eigene Projekt integrieren [13]:

npx vscode-dts dev

Zu beachten ist, dass die Dateien vscode.proposed.d.ts und vscode.d.ts nur auf dem Main-Branch im Repository zu VS Code zueinander kompatibel sind. Bei davon abweichenden VersionsstÀnden ist keine KompatibilitÀt garantiert.

Ebenfalls zu den erweiterten Möglichkeiten zĂ€hlt das Language Server Protocol, mit dem sich Funktionen fĂŒr einzelne Programmiersprachen unabhĂ€ngig vom Editor umsetzen lassen. Die Dokumentation zu VS Code hĂ€lt einen umfassenden Guide bereit, wie eine Language-Server-Erweiterung implementiert werden muss [14].

Visual Studio Code ist sowohl ein hervorragender Editor als auch eine brauchbare Entwicklungsumgebung. Die FunktionalitÀten sind umfassend und dass VS Code quelloffen und kostenfrei ist, hat offenkundig zu seiner Beliebtheit beigetragen. In vielen Communities hat sich VS Code daher einen festen Platz ergattert.

Über Erweiterungen lĂ€sst sich die Anwendung zusĂ€tzlich mit Anpassungen und Funktionen anreichern. Das gelingt bei VS Code recht einfach, denn eine Extension zu implementieren ist kein Hexenwerk. Zahlreiche Contribution Points und die VS-Code-API ermöglichen es, sich in die verschiedensten Bereiche von VS Code einzuklinken. Dadurch lassen sich auch exotische oder komplexe Anforderungen umsetzen.

Ob der Aufwand sich fĂŒr spezifische Anforderungen lohnt, mĂŒssen Entwicklerteams fallweise von Projekt zu Projekt beziehungsweise von Anforderung zu Anforderung entscheiden, zumal auch andere Entwicklungsumgebungen und Editoren das Einbinden von Erweiterungen erlauben. Diese Möglichkeit ist somit kein Alleinstellungsmerkmal von VS Code. Plattformen wie Eclipse, Visual Studio oder alle Entwicklungsumgebungen von JetBrains, etwa IntelliJ IDEA, WebStorm und Android Studio, bieten ebenfalls reichhaltige Erweiterungsmöglichkeiten an.

Im Marketplace von JetBrains stehen zurzeit rund 5.600 Plug-ins zur VerfĂŒgung [15]. Darunter befinden sich auch rund 90 kostenpflichtige Plug-ins, was fĂŒr die eine oder andere Entscheidung zur Veröffentlichung eines Plug-ins beziehungsweise einer Erweiterung sicherlich eine Rolle spielen wird (eine aktuelle Übersicht aller kostenpflichtiger Plug-ins [16] lĂ€sst sich bei JetBrains abrufen).

Am Ende bleibt die Einsicht, dass sich VS Code seit seiner Entstehung erheblich weiterentwickelt hat und in vielen Szenarien zum Einsatz kommen kann und auch kommt. Es bleibt spannend, in welche Richtung sich die Anwendung weiterentwickelt, welche Ökosysteme noch hinzutreten und ob VS Code irgendwann auch als Cloud-IDE zur VerfĂŒgung stehen wird. Im Browser lĂ€sst sich das Werkzeug seit Ende Oktober bereits als Online-Tool verwenden [17].

Dr. Fabian Deitelhoff lebt und arbeitet in Dortmund, der Metropole des Ruhrgebiets. Am CET (Centrum fĂŒr Entrepreneurship & Transfer) der TU Dortmund arbeitet er als Innovations- und Transfermanager. Er hat brickobotik gegrĂŒndet und ist als Softwareentwickler sowie Autor tĂ€tig.

(sih [18])


URL dieses Artikels:
https://www.heise.de/-6281877

Links in diesem Artikel:
[1] https://www.heise.de/hintergrund/Visual-Studio-Code-Teil-2-Den-Code-Editor-durch-Erweiterungen-ausbauen-6147512.html
[2] https://code.visualstudio.com/docs/editor/extension-marketplace
[3] https://www.heise.de/hintergrund/Visual-Studio-Code-Ein-Code-Editor-fuer-alle-s-6128966.html
[4] https://www.heise.de/hintergrund/Visual-Studio-Code-Teil-2-Den-Code-Editor-durch-Erweiterungen-ausbauen-6147512.html
[5] https://www.heise.de/hintergrund/Visual-Studio-Code-Teil-3-Eigene-Erweiterungen-implementieren-6281877.html
[6] https://code.visualstudio.com/api/references/contribution-points
[7] https://code.visualstudio.com/api/references/extension-manifest
[8] https://code.visualstudio.com/api/references/vscode-api
[9] https://microsoft.github.io/language-server-protocol/
[10] https://code.visualstudio.com/api/extension-capabilities/extending-workbench
[11] https://code.visualstudio.com/api/extension-guides/debugger-extension
[12] https://code.visualstudio.com/api/advanced-topics/remote-extensions
[13] https://github.com/microsoft/vscode-dts
[14] https://code.visualstudio.com/api/language-extensions/language-server-extension-guide
[15] https://plugins.jetbrains.com/idea
[16] https://plugins.jetbrains.com/search?isPaid=true
[17] https://www.heise.de/news/Visual-Studio-Code-laeuft-ab-sofort-im-Browser-6224465.html
[18] mailto:sih@ix.de