Developer’s Guide to Building VSCode Webview Panel with React and Messages
Are you tired of scouring the internet for hours trying to figure out how to set up a VSCode Webview Panel with React and message support? Look no further! In this article, I will provide a step-by-step guide to setting up a Webview Panel with React and message support. A Webview Panel allows you to embed web content within VSCode, which means you can create a custom UI for your extension that integrates seamlessly with the editor. Unfortunately, there is little to no documentation on this topic, but I have created a repository with a barebones skeleton to make this process as painless as possible. This article will serve as a comprehensive explanation to accompany the codebase, so you can easily set up your own Webview Panel and start coding without frustration.
In order to help you follow along, we’ve structured this article in order of importance. We’ll start by walking you through the most important file in your VSCode extension, extension.ts, and how it initializes everything for your extension. From there, we’ll dive into the PanelClass.ts file, which is essentially the ‘back-end’ of a VSCode Webview Panel, and explain how to structure it to work with VSCode Commands. Finally, we’ll cover the package.json and webpack.config.ts files, which are essential for getting your React code up and running in the Webview Panel. By the end of this article, you’ll have all the knowledge you need to get started building a powerful VSCode extension with a Webview Panel that supports messaging and React.
SRC Folder
Extension.ts File
The most important file in your VSCode extension is the extension.ts file. This is where everything for your extension is initiated, and it contains the activate function. Best practice is to use this function purely to register any commands that your extension is going to need to operate in a VSCode window. The commands here in the activate function should be linked to the PanelClass (the ‘back-end’ or brain of your extension).
PanelClass.ts File
Overview
The PanelClass.ts file is essentially the ‘back-end’ of a VSCode Webview Panel. The structure can be a little tricky, but it’s essential to understand its key components. The class is going to need some static variables and functions. These are for linking with the VSCode Commands mentioned earlier. These commands are initiated from the class without initiating an instance of the class. The Class will have a nested instance of itself as well within which the actual panel will be stored. See the image below for a visualization of the PanelClass structure.
CreateOrShow Method
One of the key components of the PanelClass is the createOrShow method. This function must be static since it is used in the activate function of the extension.ts file before initializing an instance of the class. As the name suggests, this function creates a webview panel if one doesn’t exist or shows the panel if the user is not currently viewing that panel. The column variable specifies which editor column the panel should display in.
Constructor Method
In the constructor method, you should set the extension context path. Then create a new VSCode Webview Panel and set it to the _panel variable. The parameters of this panel are: panel type, panel name, column, and an object with settings for the panel. The enableScript setting enables JavaScript in the panel, and the localResourceRoots setting links to the out directory that Webpack will populate. Make sure to use VSCode for the file path to ensure universal compatibility across operating systems.
After creating the panel is when you add event listeners to the panel. An important listener is the onDidDispose() event listener. This is where you specify what should happen when a user closes the panel. This should link to the dispose() method in the class. Additionally, the onDidReceiveMessage() event listener is where you handle receiving messages from the front-end. You can think of these messages as the equivalent of HTTP requests in a traditional web application. I recommend using a switch case for all different messages you expect to receive.
Dispose Method
The dispose method should reset the current panel variable, utilize the built-in dispose function on the panel, and clear all disposables.
GetHTMLForWebview Method
The getHTMLForWebview method should return the HTML content for the webview in a string. It’s very important to add the script defining the vscode variable to have access to it on the front end. This vscode variable is how you will send messages to the PanelClass (requests to the back-end).
<script>
//declare the vscode variable to be used in the front-end
const vscode = acquireVsCodeApi();
//send a message to confirm everything is working properly
window.onload = function() {
vscode.postMessage({ command: 'startup' });
console.log('HTML started up.');
};
</script>
Webview Directory
This is where you will store all of your React components.
App.jsx File
The React setup and utilization is standard for the most part. There is one key thing to note. You absolute must include lines 3–6 in the App.jsx file!
//Insert this into your App.tsx file after the imports.
interface vscode {
postMessage(message: any): void;
}
declare const vscode: vscode;
This is what will allow you access to the vscode variable and the ability to send and receive messages in the front-end.
GetNonce.ts File
The getNonce function is a simple function to create a unique ID where needed.
Webpack.config.ts File
The webpack.config.ts file is where you’ll find two Webpack configurations. Both are necessary. One is for the back-end (extension.ts file) and the other is for the front-end (index.tsx file). Both should output to the Out Directory.
Package.json File
In the package.json file, you’ll need to specify some information about your extension. The activationEvents property specifies any VSCode Commands that should be run on startup of the extension. The main property points to the transpiled extension.ts file. The contributes property is where you store all the commands you created in the extension.ts file. The command property needs to match up exactly with the way it’s written in extension.ts, and the title property is the name of the command used when searching VSCode commands (cmd+shift+”p”).
Out Directory
The Out Directory is where your transpiled typescript code will be outputted from webpack. No need to add anything here or create it, webpack will do this automatically if set up properly.
.Vscode Directory
The .Vscode Directory will be where you can configure custom settings for your VSCode extension. I have kept it fairly minimal in this example, one key thing to note here is the ‘preLaunchTask’ key in the configurations object. Setting the value of this key to “npm: compile” will automatically run npm compile every time before launching the extension. This will speed up development.
Media Directory
The Media Directory is where you will store all static assets for your extension and also any css files you are using in your front-end.
Wrapping Up
In conclusion, setting up a VSCode Webview Panel with React and message support can be a daunting task for developers who are new to VSCode extension development. However, by following the steps outlined in this article and utilizing the accompanying codebase, you can create a fully functional Webview Panel in no time. With this knowledge, you can now build robust VSCode extensions that provide a rich and seamless user experience. It’s important to note that while this guide provides a solid foundation, there is still much more to explore in the realm of VSCode extension development. We encourage you to continue learning and experimenting with this powerful toolset to unlock its full potential.
If you have any questions or run into roadblocks using this strategy you can contact me at michaelbenliyan@gmail.com.