Home

Awesome

@tomjs/vite-plugin-vscode

npm node-current (scoped) NPM jsDocs.io

English | 中文

Use vue/react to develop vscode extension webview, supporting esm and cjs.

In development mode, inject the same code of @tomjs/vscode-extension-webview into vscode extension code and web page code, use To support HMR; during production build, the final generated index.html code is injected into vscode extension code to reduce the workload.

Features

Install

# pnpm
pnpm add @tomjs/vite-plugin-vscode -D

# yarn
yarn add @tomjs/vite-plugin-vscode -D

# npm
npm i @tomjs/vite-plugin-vscode -D

Usage

Recommended

Setting recommended will modify some preset configurations. See PluginOptions and recommended parameter descriptions in detail.

Directory Structure

|--extension      // extension code
|  |--index.ts
|--src            // front-end code
|  |--App.vue
|  |--main.ts
|--index.html
|--dist
|  |--extension
|  |  |--index.js
|  |  |--index.js.map
|  |--webview
|  |  |--index.html
|--src            // extension code
|  |--index.ts
|--webview        // front-end code
|  |--App.vue
|  |--main.ts
|--index.html

extension

code snippet, more code see examples

const panel = window.createWebviewPanel('showHelloWorld', 'Hello World', ViewColumn.One, {
  enableScripts: true,
  localResourceRoots: [Uri.joinPath(extensionUri, 'dist/webview')],
});

// Vite development mode and production mode inject different webview codes to reduce development work
panel.webview.html = process.env.VITE_DEV_SERVER_URL
  ? __getWebviewHtml__(process.env.VITE_DEV_SERVER_URL)
  : __getWebviewHtml__(webview, context);
{
  "main": "dist/extension/index.js"
}

vue

import { defineConfig } from 'vite';
import vscode from '@tomjs/vite-plugin-vscode';
import vue from '@vitejs/plugin-vue';

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue({
      template: {
        compilerOptions: {
          isCustomElement: (tag: string) => tag.startsWith('vscode-'),
        },
      },
    }),
    vscode(),
    // Modify the extension source code entry path, and also modify the `index.html` entry file path
    // vscode({ extension: { entry: 'src/index.ts' } }),
  ],
});

react

import { defineConfig } from 'vite';
import vscode from '@tomjs/vite-plugin-vscode';
import react from '@vitejs/plugin-react-swc';

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react(), vscode()],
});

Multi-page application

See vue-import example

import path from 'node:path';
import vscode from '@tomjs/vite-plugin-vscode';

export default defineConfig({
  build: {
    plugins: [vscode()]
    rollupOptions: {
      // https://cn.vitejs.dev/guide/build.html#multi-page-app
      input: [path.resolve(__dirname, 'index.html'), path.resolve(__dirname, 'index2.html')],
      // You can also customize the name
      // input:{
      //   'index': path.resolve(__dirname, 'index.html'),
      //   'index2': path.resolve(__dirname, 'index2.html'),
      // }
    },
  },
});
process.env.VITE_DEV_SERVER_URL
  ? __getWebviewHtml__(process.env.VITE_DEV_SERVER_URL)
  : __getWebviewHtml__(webview, context);
process.env.VITE_DEV_SERVER_URL
  ? __getWebviewHtml__(`${process.env.VITE_DEV_SERVER_URL}/index2.html`)
  : __getWebviewHtml__(webview, context, 'index2');

getWebviewHtml Description

/**
 *  `[vite serve]` Gets the html of webview in development mode.
 * @param options serverUrl: The url of the vite dev server.
 */
function __getWebviewHtml__(options?: string | { serverUrl: string }): string;

/**
 *  `[vite build]` Gets the html of webview in production mode.
 * @param webview The WebviewPanel instance of the extension.
 * @param context The ExtensionContext instance of the extension.
 * @param inputName vite build.rollupOptions.input name. Default is `index`.
 */
function __getWebviewHtml__(
  webview: Webview,
  context: ExtensionContext,
  inputName?: string,
): string;

Warning

When using the acquireVsCodeApi().getState() method of @types/vscode-webview, you must use await to call it. Since acquireVsCodeApi is a simulated implementation of this method by the plugin, it is inconsistent with the original method. I am very sorry. If you have other solutions, please share them. Thank you very much.

const value = await acquireVsCodeApi().getState();

Documentation

Parameters

PluginOptions

PropertyTypeDefaultDescription
recommendedbooleantrueThis option is intended to provide recommended default parameters and behavior.
extensionExtensionOptionsConfiguration options for the vscode extension.
webviewboolean | string | WebviewOption__getWebviewHtml__Inject html code
devtoolsbooleantrueInject script code for react-devtools or vue-devtools debugging

Notice

The recommended option is used to set the default configuration and behavior, which can be used with almost zero configuration. The default is true. If you want to customize the configuration, set it to false. The following default prerequisites are to use the recommended project structure.

Webview

Inject @tomjs/vscode-extension-webview into vscode extension code and web client code, so that webview can support HMR during the development stage.

devtools

During development, support standalone development tool applications for react and vue, enabled by default.

ExtensionOptions

Based on Options of tsup, some default values are added for ease of use.

PropertyTypeDefaultDescription
entrystringextension/index.tsThe vscode extension entry file.
outDirstringdist-extension/mainThe output directory for the vscode extension file
onSuccess() => Promise<void | undefined | (() => void | Promise<void>)>undefinedA function that will be executed after the build succeeds.

WebviewOption

PropertyTypeDefaultDescription
namestring__getWebviewHtml__The inject method name
cspstring<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src {{cspSource}} 'unsafe-inline'; script-src 'nonce-{{nonce}}' 'unsafe-eval';">The CSP meta for the webview

Additional Information

ParameterDevelopment Mode DefaultProduction Mode Default
sourcemaptruefalse
minifyfalsetrue

Environment Variables

Vite plugin variables

vscode extension use.

VariableDescription
VITE_DEV_SERVER_URLThe url of the vite dev server
VariableDescription
VITE_WEBVIEW_DISTvite webview page output path

Debug

Run Debug Extension through vscode to debug. For debugging tools, refer to Official Documentation

launch.json is configured as follows:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug Extension",
      "type": "extensionHost",
      "request": "launch",
      "args": ["--extensionDevelopmentPath=${workspaceFolder}"],
      "outFiles": ["${workspaceFolder}/dist/extension/*.js"],
      "preLaunchTask": "npm: dev"
    },
    {
      "name": "Preview Extension",
      "type": "extensionHost",
      "request": "launch",
      "args": ["--extensionDevelopmentPath=${workspaceFolder}"],
      "outFiles": ["${workspaceFolder}/dist/extension/*.js"],
      "preLaunchTask": "npm: build"
    }
  ]
}

tasks.json is configured as follows:

{
  "version": "2.0.0",
  "tasks": [
    {
      "type": "npm",
      "script": "dev",
      "problemMatcher": {
        "owner": "typescript",
        "fileLocation": "relative",
        "pattern": {
          "regexp": "^([a-zA-Z]\\:/?([\\w\\-]/?)+\\.\\w+):(\\d+):(\\d+): (ERROR|WARNING)\\: (.*)$",
          "file": 1,
          "line": 3,
          "column": 4,
          "code": 5,
          "message": 6
        },
        "background": {
          "activeOnStart": true,
          "beginsPattern": "^.*extension build start*$",
          "endsPattern": "^.*extension (build|rebuild) success.*$"
        }
      },
      "isBackground": true,
      "presentation": {
        "reveal": "never"
      },
      "group": {
        "kind": "build",
        "isDefault": true
      }
    },
    {
      "type": "npm",
      "script": "build",
      "group": {
        "kind": "build",
        "isDefault": true
      },
      "problemMatcher": []
    }
  ]
}

Examples

First execute the following command to install dependencies and generate library files:

pnpm install
pnpm build

Open the examples directory, there are vue and react examples.

Related

Important Notes

v3.0.0

Breaking Updates: