tomjs / vite-plugin-vscode

用 vue/react 来开发 vscode extension webview ,支持 esm 和 cjs。Use vue/react to develop vscode extension webview, supporting esm and cjs.
MIT License
29 stars 1 forks source link
extension hmr hot plugin react vite vscode vue webview

@tomjs/vite-plugin-vscode

npm node-current (scoped) NPM Docs

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

Property Type Default Description
recommended boolean true This option is intended to provide recommended default parameters and behavior.
extension ExtensionOptions Configuration options for the vscode extension.
webview boolean | string | WebviewOption __getWebviewHtml__ Inject html code

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.

ExtensionOptions

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

Property Type Default Description
entry string extension/index.ts The vscode extension entry file.
outDir string dist-extension/main The output directory for the vscode extension file
onSuccess () => Promise<void \| undefined \| (() => void \| Promise<void>)> undefined A function that will be executed after the build succeeds.

WebviewOption

Property Type Default Description
name string __getWebviewHtml__ The inject method name
csp string <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

Parameter Development Mode Default Production Mode Default
sourcemap true false
minify false true

Environment Variables

Vite plugin variables

vscode extension use.

Variable Description
VITE_DEV_SERVER_URL The url of the vite dev server
Variable Description
VITE_WEBVIEW_DIST vite 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