跳转至

VS Code 扩展开发

预计阅读时长 : 13 分钟

关于 VS Code 扩展开发的详细流程,可以参考官方文档社区中文版 ⧉以及 VSCode 插件开发全攻略 ⧉ 。本文主要是整理在如何开源项目基础上,根据个性化需求进行定制的过程。

准备工作

开发 VS Code 扩展的最佳方式,就是使用 VS Code 本身。

请先安装好 Node.js 和 Git,然后安装 Yeoman 和 VS Code Extension Generator:

npm install -g yo generator-code

如果我们是要修改其他的开源扩展,那么 Clone 源代码并在 VS Code 中设置成新的项目。按下 F5,你会立即看到一个新启动的 扩展测试窗口,其中就运行着开发中的扩展。

之后如果在 扩展开发窗口 中进行了修改,那么只需要点击 按钮,都会实时在 测试窗口 中生效,这让整个的调试过程非常地顺畅。

目录结构

一个标准的 VS Code 扩展项目,其目录结构如下:

扩展项目目录结构
.
├── .vscode
   ├── launch.json     // 扩展加载和调试的配置
   └── tasks.json      // 配置TypeScript编译任务
├── .gitignore          // 忽略构建输出和node_modules文件
├── README.md           // 一个友好的扩展文档
├── src
   └── extension.ts    // 扩展源代码
├── package.json       // 扩展配置
   ├── package-lock.json     // 扩展依赖
├── tsconfig.json       // TypeScript配置

其中,我们需要进行定制化的,主要是负责交互定义的 package.json 和负责逻辑实现的 src/extension.ts

扩展配置

每个 VS Code 扩展都必须包含一个 package.json,其中定义了扩展的必要信息。

package.json 配置中,混合了 Node.js 字段,如:scripts、dependencies,还加入了一些 VS Code 独有的字段,如:publisher、activationEvents、contributes 等。

关于这些 VS Code 字段的详细说明都在 扩展文件参考 ⧉ 中可以找到。本文中仅根据实际的需要,介绍一下其中比较重要的部分。

详情描述

详情描述部分主要是用于在 VS Code 扩展市场中展示的信息,包括扩展的名称、描述、版本、作者、许可证、图标等,详细解读参见 配置字段说明 ⧉

详情描述
{
  "name": "Writer AI", //(1)
  "displayName": "GPT extension for Writer- Writer AI", //(2)
  "description": "🚀 Use GPT Copilot right inside VS Code to enhance and automate your writing experence", //(3)
  "version": "0.0.1", //(4)
  "publisher": "Libukai", //(5)
  "private": false, //(6)
  "icon": "resources/chatbot.png", //(7)
  "license": "Apache-2.0", //(8)
  "repository": {
    //(9)
    "type": "git",
    "url": "https://github.com/libukai/WriterAI"
  },
  "engines": {
    //(10)
    "vscode": "^1.84.2"
  },
  "sponsor": {
    //(11)
    "url": "https://aikebang.net"
  },
  "categories": [
    //(12)
    "Markdown",
    "Snippets",
    "AI",
    "Notebooks"
  ],
  "keywords": [
    //(13)
    "chatgpt",
    "gpt",
    "openai",
    "copilot",
    "ai"
  ],
  "galleryBanner": {
    //(14)
    "color": "#041621",
    "theme": "dark"
  }
}
  1. 扩展的内部名称,用于 VS Code 扩展市场的搜索和依赖关系管理。
  2. 扩展在 VS Code 用户界面上显示的名称。
  3. 描述了扩展的功能,即在 VS Code 中使用 GPT Copilot 来提高和自动化写作体验。
  4. 扩展的当前版本,遵循语义化版本控制 ⧉
  5. 发布扩展的个人或组织名称。
  6. 表明该扩展是否是私有的,可能不在公共市场上列出。
  7. 扩展的图标文件路径。
  8. 扩展使用的许可证类型。
  9. 指向扩展源代码的仓库位置。
  10. 指定扩展依赖的 VS Code 版本。
  11. 提供赞助商的信息。
  12. 扩展的类别,用于在 VS Code 扩展市场中进行分类。
  13. 扩展的关键字,用于在 VS Code 扩展市场中进行搜索。

交互配置

交互配置部分主要是用于定义扩展在 VS Code 中的交互方式,包括命令、菜单、配置等。这部分的内容配置相对复杂,具体细节参见 交互详细解读 ⧉

交互配置
{
  "contributes": {
    "commands": [
      {
        "command": "mywiki.createNote",
        "title": "Create Note",
        "enablement": "!commentIsEmpty"
      }
    ],
    "menus": {
      "commandPalette": [
        {
          "command": "mywiki.createNote",
          "when": "false"
        }
      ],
      "comments/commentThread/title": [
        {
          "command": "mywiki.deleteNote",
          "group": "navigation",
          "when": "commentController == comment-scribeai && !commentThreadIsEmpty"
        }
      ]
    },
    "configuration": {
      "title": "ScribeAI",
      "properties": {
        "scribeai.ApiKey": {
          "type": "string",
          "default": "",
          "scope": "application",
          "markdownDescription": "Your personal OpenAI API key. If you don't have one, generate a new one [here](https://beta.openai.com/account/api-keys).\n\nDon't forget to [restart your extension](command:workbench.action.reloadWindow) once you finished configuring so that your extension gets loaded with the new configurations."
        }
      }
    }
  }
}

编译配置

编译配置部分用来定义调试和运行的相关配置,包括扩展在编译时的依赖,运行时启动路径,以及相应的运行脚本等。

编译配置
{
  "activationEvents": [
    //(1)
    "onStartupFinished"
  ],
  "main": "./out/extension.js", //(2)
  "devDependencies": {
    //(3)
    "@types/node": "^20.8.7",
    "@types/vscode": "~1.83.1",
    "@typescript-eslint/eslint-plugin": "^5.59.7",
    "@typescript-eslint/parser": "^5.59.7",
    "eslint": "^8.41.0",
    "typescript": "^4.9.5"
  },
  "dependencies": {
    //(4)
    "openai": "^4.12.4"
  },
  "scripts": {
    //(5)
    "vscode:prepublish": "npm run compile", // (6)
    "compile": "tsc -p ./", // (7)
    "watch": "tsc -watch -p ./", // (8)
    "lint": "eslint \"src/**/*.ts\"" // (9)
  }
}
  1. 指定了何时应激活扩展。在这个例子中,扩展在 VS Code 的启动过程完成后被激活,具体说明详见激活事件说明 ⧉
  2. 指向扩展的主入口点,在这个例子中是编译后生成的 ./out/extension.js
  3. 列出了只在开发和测试时需要的包。当项目被用作另一个项目的依赖项时,这些包不会被安装。这里,它包括 TypeScript、ESLint 及其相关包。
  4. 列出了项目运行所依赖的包。当项目被安装为另一个项目的依赖项时,这些包将由 npm 安装。在这个例子中,它包括 openai 包。
  5. 字段是一个字典,包含了在包的生命周期中的各个时刻运行的脚本命令。
  6. 脚本在包准备发布之前运行。
  7. 脚本用于编译 TypeScript 代码。
  8. 脚本用于在文件更改时重新编译文件。
  9. 脚本用于在源文件上运行 ESLint。

逻辑实现

扩展的主要逻辑实现,是依赖 src/extension.ts 文件来完成的。其中,与 VS Code 的交互主要是通过 vscode 模块来实现。

这块的具体实现,可以参考 扩展功能列表 ⧉,也可以根据开源项目的代码情况进行相应的魔改。

扩展打包

在完成了扩展的开发之后,我们可以将其直接打包和分发,以便直接用于其他人的测试和使用。

首先,我们需要安装官方提供的 vsce 工具:

npm install -g @vscode/vsce

然后,我们可以使用 vsce package 命令来打包扩展:

vsce package
Executing prepublish script 'npm run vscode:prepublish'...

> WriterAI@0.0.1 vscode:prepublish /Users/likai/Github/Tools/WriterAI
> npm run compile

> WriterAI@0.0.1 compile /Users/likai/Github/Tools/WriterAI
> tsc -p ./

This extension consists of 926 files, out of which 200 are JavaScript files. For performance reasons, you should bundle your extension: https://aka.ms/vscode-bundle-extension . You should also exclude unnecessary files by adding them to your .vscodeignore: https://aka.ms/vscode-vscodeignore
DONE Packaged: /Users/likai/Github/Tools/WriterAI/WriterAI-0.0.1.vsix (926 files, 5.86MB)
Waiting for the debugger to disconnect...

这个命令会在当前目录下生成一个 .vsix 文件,这个文件就是我们的扩展包,可以直接在 VS Code 中安装使用。

对于复杂的项目,我们也可以 使用 webpack 打包扩展 ⧉,进一步提升扩展的性能。

扩展发布

在小范围测试完毕确认没有问题之后,我们就可以考虑将扩展发布到 VS Code 扩展市场中,供更多的人使用了。

首先,需要在 Azure DevOps 中创建自己的组织,然后在组织主页获取 Personal access tokens,这个 token 需要开放 Marketplace 下的 Manage 权限。整个操作流程,详见官方指引文档 ⧉

然后,我们需要使用 vsce login 命令,以及配置好的 Personal Access Token 来验证我们的发布者身份。具体的发布者信息可以登陆 Marketplace Publisher ⧉ 后查看。

vsce login <publisher id>
https://marketplace.visualstudio.com/manage/publishers/
Personal Access Token for publisher '<publisher id>':
****************************************************
The Personal Access Token verification succeeded for the publisher '<publisher id>'.

最后,使用 vsce publish 命令来发布扩展:

vsce publish

为了提升在 VS Code 扩展市场中的展示效果,我们可以通过配置 README.mdLICENSECHANGELOG.md 来丰富扩展的说明。

  1. 扩展根目录下的 README.md 文件将用于填充扩展的市场页面内容。
  2. 扩展根目录下的 LICENSE 文件将被用作扩展许可证的内容,至于选择什么类型的许可证,可以参考 如何选择开源许可证? ⧉
  3. 扩展根目录下的 CHANGELOG.md 文件将被用作扩展的变更日志的内容,变更日志的规则可以参考 Keep a Changelog ⧉