For Front Matter and another extension, I am currently developing. I use the Visual Studio Code WebView API heavily as it provides fully customizable views for your panels or tabs. It allows any company and developer to create their own unique experiences.
One of the things I did for a long time was manually hitting the refresh button each time I updated the code. In case when you are working with a WebView, this experience is clumsy.
We are used to having Hot Module Replacement (HRM) for web projects, but unfortunately, this is not automatically available for VS Code extension development.
To improve the experience when working with WebViews in VS Code, I tried to make HMR work for create-react-app
and webpack dev server
. In this article, I will share the steps I had to take to make it work for CRA, but you will have to do a similar configuration in both cases.
InfoIn Front Matter, the React app is part of the solution and generates the bundle via a separate webpack config and makes use of the webpack dev server.
The approach
I choose to separate the project and use the CRA for the other project. You can create the React project anywhere you want, but a mono-repo approach might be appropriate as you will have to move some files during the packaging of your extension.
As a starting point, I took the WebView documenation.
WebView base HTML
In the sample, a getWebviewContent
method in which the HTML is defined. To make React work in the WebView you have to change the code as follows:
|
|
In the method, a couple of things have changed:
- There is logic added when the extension is running in development or production mode;
- Some React HTML requirements have been added.
The production/development logic is required to ensure where the JS and CSS file gets loaded. In development, this will be from the localhost
. During production, it loads from within the extension.
Webpack configuration
To simplify the JS and CSS references, I made some webpack changes. If you are using CRA, you best use the react-app-rewired
dependency to override the webpack config.
My config-overrides.js
looks as follows:
|
|
The most important line here is the config.output.publicPath
, set to your local server. We need to provide it to make sure absolute paths are used for referencing files to load. As the code runs in the WebView, there is no actual HTML page, and the location of your webpage will be the VS Code instance: vscode-webview://
.
If you do not provide the publicPath
, only the first load runs fine. Once you update the code, you will notice that the hot-update
files fail to fetch.
Looking at the URL from where the file loads, you’ll spot the vscode-webview://
path.
When providing the publicPath
it works as expected.
What about packaging?
When you build your two solutions, you will have to ensure that the JS bundle and CSS file are copied/moved to the correct folder. In my case, I put these two files in the dist
folder of the VS Code extension just before packaging it.
Important: Be aware it could be you’ll have to make other changes to your webpack configuration to make sure the assets are correctly loaded.