搭建基于react webview的vscode插件

64 阅读3分钟

搭建基于react webview的vscode插件

准备工作

确保你本机安装了最新的vscode以及git和Node.js,如果没有,遵照下边官方链接下载安装。

vscode下载

git下载

Node.js下载

安装完成后可以在控制台看到类似如下信息。

PS C:\Users\xuruo>code --version
1.108.0
94e8ae2b28cb5cc932b86e1070569c4463565c37
x64

PS C:\Users\xuruo>git --version
git version 2.42.0.windows.2

PS C:\Users\xuruo>node --version
v22.12.0

PS C:\Users\xuruo>npm --version
10.9.0

创建你的第一个vscode插件

从cline的代码中可以看到他是从hello-world-ract-vite作为基础开始构建的。 让我们从克隆minicline项目代码开始创建我们的第一个vscode插件项目。 minicline的第一个代码commit就是从拷贝hello-world-ract-vite代码开始的。

PS D:\git> git clone https://github.com/xuruoyu1979/minicline.git

PS D:\git> git cd miniclone

PS D:\git> git checkout f1b5631dc1196a2b082165e603840870248ca5fc

PS D:\git\miniclone> git npm run install:all

如果一切正常,会看到类似如下的输出。

> hello-world-react-vite@0.0.1 install:all
> npm install && cd webview-ui && npm install


added 182 packages, and audited 183 packages in 5s
...
To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

编译webview

PS D:\git\minicline> npm run build:webview

> hello-world-react-vite@0.0.1 build:webview
> cd webview-ui && npm run build


> hello-world@0.0.1 build
> tsc && vite build

vite v2.9.13 building for production...
transforming (1) index.htmlBrowserslist: caniuse-lite is outdated. Please run:
  npx browserslist@latest --update-db
  Why you should do it regularly: https://github.com/browserslist/browserslist#browsers-data-updating
...
✓ 319 modules transformed.
build/index.html         0.37 KiB
build/assets/index.css   0.10 KiB / gzip: 0.10 KiB
build/assets/index.js    308.26 KiB / gzip: 85.31 KiB

运行你的第一个插件

克隆下来的minicline项目下已经自带了 .vscode/launch.json ,里边有运行vscode extension的配置,从vscode左侧 RUN and DEBUG 视图点击 Run Extension ,会启动一个新的vscode实例,里边已经加载了我们的minicline插件,用组合键 CTRL+SHIFT+P 打开命令窗口,在里边输入 Hello World, 找到 Hello World (React + Vite): Show命令,点击会打开新的webview显示在编辑器区域,如下图所示

chapter-1-1.png 点击 Howdy! 按钮,右下方会显示消息 Hey there partner! 🤠

总结

本章我们运行了第一个webview插件,webview相对于普通的vscode插件和普通的react webapp的区别在于,它是运行在独立的sandbox里边的,所以不同于运行在web browser和vscode extension host,它不能访问外部资源。所以需要访问外部数据需要通过和vscode extension host中运行的插件代码交互,比如本章中我们点击 Howdy! 按钮后vscode显示对应消息就是通过webview往vscode extension host发送消息实现的。

具体代码参考如下。

webview-ui/src/App.tsx

  function handleHowdyClick() {
    vscode.postMessage({
      command: "hello",
      text: "Hey there partner! 🤠",
    });
  }

src/panels/HelloWorldPanel.ts

  private _setWebviewMessageListener(webview: Webview) {
    webview.onDidReceiveMessage(
      (message: any) => {
        const command = message.command;
        const text = message.text;

        switch (command) {
          case "hello":
            // Code that should run in response to the hello message command
            window.showInformationMessage(text);
            return;
          // Add more switch case statements here as more webview message commands
          // are created within the webview context (i.e. inside media/main.js)
        }
      },
      undefined,
      this._disposables
    );
  }