English | 中文
Use
vue/reactto develop vscode extension webview, supportingesmandcjs.
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.
- Use tsup to quickly build
extension code - Simple configuration, focus on business
- Support
esmandcjs - Support webview
HMR - Support Multi-Page App
- Supports
vueandreactand other frameworks supported byvite
# pnpm
pnpm add @tomjs/vite-plugin-vscode -D
# yarn
yarn add @tomjs/vite-plugin-vscode -D
# npm
npm i @tomjs/vite-plugin-vscode -DSetting recommended will modify some preset configurations. See PluginOptions and recommended parameter descriptions in detail.
- By default,
recommended:truewill be based on the following directory structure as a convention.
|--extension // extension code
| |--index.ts
|--src // front-end code
| |--App.vue
| |--main.ts
|--index.html
- Zero configuration, default dist output directory
|--dist
| |--extension
| | |--index.js
| | |--index.js.map
| |--webview
| | |--index.html
- If you want to modify the
extensionsource code directory tosrc, you can set{ extension: { entry: 'src/index.ts' } }
|--src // extension code
| |--index.ts
|--webview // front-end code
| |--App.vue
| |--main.ts
|--index.html
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);package.json
{
"main": "dist/extension/index.js"
}vite.config.ts
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' } }),
],
});vite.config.ts
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()],
});See vue-import example
vite.config.ts
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'),
// }
},
},
});- page one
process.env.VITE_DEV_SERVER_URL
? __getWebviewHtml__(process.env.VITE_DEV_SERVER_URL)
: __getWebviewHtml__(webview, context);- page two
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;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();- index.d.ts provided by unpkg.com.
| 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.
- The output directory is based on the
build.outDirparameter ofvite, and outputsextensionandsrctodist/extensionanddist/webviewrespectively. - Other behaviors to be implemented
Webview
Inject @tomjs/vscode-extension-webview into vscode extension code and web client code, so that webview can support HMR during the development stage.
- vite serve
- extension: Inject
import __getWebviewHtml__ from '@tomjs/vscode-extension-webview';above the file that calls the__getWebviewHtml__method - web: Add
<script>tag to index.html and inject@tomjs/vscode-extension-webview/clientcode
- extension: Inject
- vite build
- extension: Inject
import __getWebviewHtml__ from '@tomjs/vite-plugin-vscode-inject';above the file that calls the__getWebviewHtml__method If is string, will set inject method name. Default is__getWebviewHtml__.
- extension: Inject
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. |
| 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 |
{{cspSource}}: webview.cspSource{{nonce}}: uuid
- Default values for
extensionwhen the relevant parameters are not configured
| Parameter | Development Mode Default | Production Mode Default |
|---|---|---|
| sourcemap | true |
false |
| minify | false |
true |
vscode extension use.
developmentmode
| Variable | Description |
|---|---|
VITE_DEV_SERVER_URL |
The url of the vite dev server |
productionmode
| Variable | Description |
|---|---|
VITE_WEBVIEW_DIST |
vite webview page output path |
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": []
}
]
}First execute the following command to install dependencies and generate library files:
pnpm install
pnpm buildOpen the examples directory, there are vue and react examples.
- react: Simple react example.
- vue: Simple vue example.
- vue-import: Dynamic import() and multi-page examples.
- @tomjs/vscode: Some utilities to simplify the development of VSCode Extensions.
- @tomjs/vscode-dev: Some development tools to simplify the development of vscode extensions.
- @tomjs/vscode-webview: Optimize the
postMessageissue betweenwebviewpage and vscode extensions