VSCode plug-in development series tutorial plan

Plan can not catch up with change, iteration at any time, welcome to leave a message

  • Create a new plugin using scaffolding ☑️
  • This section describes package.json configuration
  • TreeView
  • The WebView ☑ ️
  • Listen for code input
  • How to publish to the plug-in marketplace ☑️

Recently developed a VSCode plug-in called “I love digging gold”, mainly around the Webview API to achieve. As a front-end engineer, just give you a Webview, it won’t move the earth, but we can make a lot of cool plug-ins. For example, the bully plugin, rainbow ass wife plugin and so on.

In fact, VSCode is also based on the electron framework desktop software, which means that all the interfaces you see in VSCode are essentially web pages. So how do I display the page again in the page? As you can imagine, iframe.

Debug the Webview

In the VSCode command panel, enter Open Webview Developer Tools to Open the Webview console

It was the iframe ~

Must your plugin use a Webview?

The official document in English address: code.visualstudio.com/api/extensi…

The VSCode team wants add-on developers to ask the following questions:

  • Does this feature really need to work in VS Code? Would it be better as a separate application or website?
  • useWebviewIs that the only way to do it? Can you use the regular VS Code API instead?

Create WebviewPanel

const panel = vscode.window.createWebviewPanel(
  'webview'."Test webview",
  vscode.ViewColumn.One
);
panel.webview.html = '< HTML > Hello, I'm Webview
      '
Copy the code

This will create a Webview and render the HTML content.

It looks very simple to use, but in the actual use of Webview plug-in development process, or encountered a lot of pits:

Pit 1: Use local resources

Webviews in VSCode cannot directly use local resources in relative paths. For example, in the following code, we introduce a CSS, a JS, and an image in the body.

Writing this directly will not load these resources

  • Solution 1

Through a special protocol header vscode-resource: the absolute path of the resource file, in order not to affect our normal web development, we can package a method to read the HTML content from the local file, unified replacement of all resource paths and then assigned to panel.webview.html

function getWebViewContent(context, templatePath) {
	const resourcePath = path.join(context.extensionPath, templatePath);
	const dirPath = path.dirname(resourcePath);
	let html = fs.readFileSync(resourcePath, 'utf-8');
    html = html.replace(/(.(m, $1, $2) = > {
		if($2.indexOf("https://") <0)return $1 + vscode.Uri.file(path.resolve(dirPath, $2)).with({ scheme: 'vscode-resource' }).toString() + '"';
		else return $1 + $2+'"';
	});
	return html;
}
Copy the code

In this way, when we develop the web page, we can write the relative path normally.

Note: If you are using Vue or some other front-end framework for plug-in Webview development, pay attention to the introduction of resources. The method encapsulated above only replaces the hardcode resources in the page.

  • Solution 2

Use iframe to introduce local path HTML, but VSCode’s webview has very limited restrictions on iframe, except to display web pages and interact with node environment.

Pit 2: Javascript is allowed

Javascript is not supported by default

  • The solution

Add option and set enableScritps to true, which defaults to false.

Pit 3: Cookie and localstorage

Cookie and localStorage work, but!!

When VSCode restarts, it’s all cleaned up, so it doesn’t work.

  • The solution

Call the VSCode node environment to save, where the WebView and the VSCode plug-in environment need to communicate.

Pit 4: Webview content is released

When the TAB pannel where the Webview is located enters the background (for example, it has been switched to another TAB), the content in the Webview is cleared and the memory usage is released. The HTML content is reloaded when you cut back again.

  • The solution

Enable retainContextWhenHidden

Message communication

  1. The plugin sends a message, and the Webview receives the message

    • JS in plugins
    panel.webview.postMessage({text: 'Hello, THIS is plug-in.'});
    Copy the code
    • JS in the Webview
    window.addEventListener('message'.function(e){
      console.log(e.data.text);
    })
    Copy the code
  2. The Webview sends messages, and the plug-in receives messages

    • JS in the Webview
    // initialize vscode plugin API, nothing special, mainly postMessage
    var vscode = acquireVsCodeApi();
    
    vscode.postMessage({
      text: 'Hi, I'm Webview.'
    })
    Copy the code
    • JS in plugins
    panel.webview.onDidReceiveMessage(function(data) {
      console.log(data.text);
    });
    Copy the code

Cookies and localstorage, for example, can encapsulate messages and save them locally through the plug-in Node environment

var vscode = acquireVsCodeApi();
function setLocalStorage(k,v){
  vscode.postMessage({
    command: 'setLocalStorage'.key:k,
    value:v
  })
}
Copy the code
panel.webview.onDidReceiveMessage(function(data) {
  if(data.command == 'setLocalStorage') {/ / use lowdblowdb.set(data.key,data.value).write(); }});Copy the code

The official Demo

  • Github.com/microsoft/v…
  • Github.com/microsoft/v…