VScode插件开发
Published:
本文将介绍如何快速构建一个自己的VSCode插件,主要使用语言为TypeScript。
快速开始
根据接下来的步骤,我们可以创建一个使用命令激活,输出 hello world 的插件
安装 Yeoman 和 VS code generator
npm install -g yo generator-code
脚手架——用于自动生成 VScode 插件模板项目
生成模板项目
yo code
根据需要进行选择(若为首次尝试,可根据下列选项一路回车)
# ? What type of extension do you want to create? New Extension (TypeScript) # ? What's the name of your extension? HelloWorld ### Press <Enter> to choose default for all options below ### # ? What's the identifier of your extension? helloworld # ? What's the description of your extension? LEAVE BLANK # ? Initialize a git repository? Yes # ? Bundle the source code with webpack? No # ? Which package manager to use? npm
运行 打开刚刚创建好的项目
code ./helloworld
F5 运行项目调试
- 此时将打开一个新的 VScode 窗口用于插件调试,用于调试的窗口标题栏会标注”[Extension Development Host]”便于区分
⬆+command+P 打开命令搜索框,输入 hello world,运行相关命令
在右下角看到弹出的通知框,即为命令运行成功,插件已激活
模板项目解析
根据上一节的步骤,我们成功创建了一个 VScode 插件,接下来,来看看这个项目中的结构与具体实现吧。
目录结构
.
├── .vscode
│ ├── launch.json // 插件加载和调试的配置
│ └── tasks.json // 配置TypeScript编译任务
├── .gitignore // 忽略构建输出和node_modules文件
├── README.md // 一个友好的插件文档
├── src
│ └── extension.ts // 插件源代码
├── package.json // 插件配置清单
├── tsconfig.json // TypeScript配置
针对基本功能的开发,我们目前只需要关注package.json和extension.ts这两个文件,如果你对其他配置文件感兴趣,可以查看 VScode 的官方文档 和 TypeScript 的官方使用手册。
插件配置清单-package.json
{
"name": "helloworld",
"displayName": "HelloWorld",
"description": "",
"version": "0.0.1",
"engines": {
"vscode": "^1.58.0" // 这里指定了插件运行所需的VScode版本
},
"categories": [
"Other" // 插件类型(具体见下一节介绍)
],
"activationEvents": [
"onCommand:helloworld.helloWorld" // 绑定激活事件
],
"main": "./out/extension.js",
"contributes": {
"commands": [
// 定义、发布命令helloworld.helloworld
{
"command": "helloworld.helloWorld",
"title": "Hello World"
}
]
},
"scripts": {
"vscode:prepublish": "npm run compile",
"compile": "tsc -p ./",
"watch": "tsc -watch -p ./",
"pretest": "npm run compile && npm run lint",
"lint": "eslint src --ext ts",
"test": "node ./out/test/runTest.js"
},
"devDependencies": {
"@types/vscode": "^1.58.0",
"@types/glob": "^7.1.3",
"@types/mocha": "^8.2.2",
"@types/node": "14.x",
"eslint": "^7.27.0",
"@typescript-eslint/eslint-plugin": "^4.26.0",
"@typescript-eslint/parser": "^4.26.0",
"glob": "^7.1.7",
"mocha": "^8.4.0",
"typescript": "^4.3.2",
"vscode-test": "^1.5.2"
}
}
源代码-extension.ts
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
// 引入VScode提供的API
import * as vscode from "vscode";
// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
// 当插件激活时执行此函数,激活条件即为package.json中注册的命令执行
export function activate(context: vscode.ExtensionContext) {
// Use the console to output diagnostic information (console.log) and errors (console.error)
// This line of code will only be executed once when your extension is activated
console.log('Congratulations, your extension "helloworld" is now active!');
// The command has been defined in the package.json file
// Now provide the implementation of the command with registerCommand
// The commandId parameter must match the command field in package.json
// 将package.json中定义的命令与对应事件注册绑定
let disposable = vscode.commands.registerCommand("helloworld.helloWorld", () => {
// The code you place here will be executed every time your command is executed
// Display a message box to the user
// 在右下角显示通知框
vscode.window.showInformationMessage("Hello World from HelloWorld!");
});
context.subscriptions.push(disposable);
}
// this method is called when your extension is deactivated
// 在插件停用前执行
export function deactivate() {}
最后,让我们来梳理一下,首先你需要在 package.json 中定义你将用到的命令,并注册能够激活组件的命令,如:输入命令”hello world”、打开 JavaScript 文件、按下组合按键等;接下来,在 extension.ts 的 activate 函数中将你定义的命令与将插件激活后命令触发的函数绑定起来,并在 deactivate 函数中进行插件停用前的清除,这样就可以实现一个简单的插件啦~
插件功能
上一节中,我们对 VScode 插件的结构进行了解析,几乎所有的插件都是根据这样的结构来进行开发的,本节中,我们将介绍 VScode 为哪些功能提供了可扩展的 API
VScode 插件可提供的功能主要为以上五类:
首先是通用的如选择文件、文件夹,收集用户输入,存储工作区或全局数据等基本的功能;
其次是主题相关的,如源代码颜色设置,UI 主题设置,icon 图标设置等;
第三是语言特性,分为声明式与程序式,声明式主要是文本编辑基础的特性,不包含代码逻辑,如括号匹配显示、自动缩进、语法高亮等,而程序式则需要结合程序语言逻辑,如悬停提示、跳转定义、格式化等;
第四是工作台 UI 的扩展,可以增加右键菜单、状态栏、侧边栏、webview 等,具体对应关系见下图;
最后,是调试相关的功能,可以利用 VScode 提供的调试功能或自己的调试功能来进行开发。
以上仅为各类插件功能的概要介绍,具体的 API 见官方文档
VScode 命令系统
VScode 是微软使用 electron 框架,100%TypeScript 语言开发的桌面端代码编辑器软件,我们能够依照规范自由添加插件,主要源于其平台/插件架构风格的设计,下面将对 VScode 的设计做简要介绍
VScode 采用多进程架构,上图为简要展示,
- 主进程:VSCode 的入口进程,负责如窗口管理、进程间通信、自动更新等全局任务
- 渲染进程:负责一个 Web 页面的渲染
- 插件宿主进程:每个插件的代码都会运行在一个独属于自己的 NodeJS 环境的宿主进程中,插件不允许访问 UI
- Debug 进程:Debugger 相比普通插件做了特殊化
- Search 进程:搜索是一类计算密集型的任务,单开进程保证软件整体体验与性能
如上图,VScode 选取的命令系统相较网状的结构更为扁平,能够更加高效地进行功能的调用。
扩展阅读
VScode 官方文档:https://code.visualstudio.com/api
VScode 源码:https://github.com/microsoft/vscode
TypeScript 官方文档:https://www.typescriptlang.org/docs/
TypeScript 类型体操:https://github.com/type-challenges/type-challenges