插件结构解析
在上一篇文档中,你得到了一个最基础的可以运行的插件。它在后台是如何运行的呢?
Hello World
做了三件事:
- 注册了一个onCommand 激活事件:
onCommand:helloworld.helloWorld
,因此当用户运行Hello World
命令时,该插件被激活。
- 使用 Contribution 配置项
contributes.commands
,让Hello World
命令出现在命令面板中,并绑定到helloworld.helloWorld
中。
- 使用 VS Code API
commands.registerCommand
,将注册的命令 IDhelloworld.helloWorld
绑定在了一个函数上。
在 VS Code 中编写插件,理解这三个概念至关重要:
- 激活事件:你的插件所激活的事件。
- Contribution 配置项: 你在
package.json
插件声明文件 中声明的静态的配置。
- VS Code API: 你可以在插件中调用的一系列的 JavaScript 接口。
一般来说,你的插件应该同时使用 Contribution 配置项和 VS Code API,来一起扩展 VS Code 的功能。插件能力概述可以帮助你找到你所需要的 Contribution 配置项和 VS Code API。
我们来仔细观察 Hello World
示例,看看这些概念是如何应用在插件开发中的。
插件文件结构
.
├── .vscode
│ ├── launch.json // 插件启动和调试的配置
│ └── tasks.json // TypeScript 编译构建的配置
├── .gitignore // node_modules 和构建输出的忽略配置
├── README.md // 你的插件的功能描述
├── src
│ └── extension.ts // 插件源代码
├── package.json // 插件配置信息
├── tsconfig.json // TypeScript 配置
你可以查阅更多的关于配置文件的信息:
launch.json
用于配置 VS Code 调试
tasks.json
用于定义 VS Code 的任务
tsconfig.json
请参考 TypeScript 手册
然而,我们只需要关注 package.json
和 extension.ts
,这对理解 Hello World
插件至关重要。
插件配置清单
每个 VS Code 插件必须有一个 package.json
文件,作为它的 配置清单。package.json
文件包含了 Node.js 的配置(如 scripts
和 devDependencies
),和 VS Code 独有的配置(如publisher
、 activationEvents
和 contributes
)。你可以在配置清单参考中查询到每个 VS Code 独有的字段的含义。下面是一些重要的字段:
name
和publisher
:VS Code 使用<publisher>.<name>
作为扩展的唯一 ID。举个例子,示例Hello World
的 ID 是vscode-samples.helloworld-sample
。VS Code 使用这个 ID 来识别你的插件。
main
:插件的入口点。
activationEvents
和contributes
:激活事件 和 Contribution 配置项。
engines.vscode
:这项标明了插件所依赖的最低的 VS Code 版本。
{
"name": "helloworld-sample",
"displayName": "helloworld-sample",
"description": "HelloWorld example for VS Code",
"version": "0.0.1",
"publisher": "vscode-samples",
"repository": "https://github.com/microsoft/vscode-extension-samples/helloworld-sample",
"engines": {
"vscode": "^1.51.0"
},
"categories": ["Other"],
"activationEvents": [],
"main": "./out/extension.js",
"contributes": {
"commands": [
{
"command": "helloworld.helloWorld",
"title": "Hello World"
}
]
},
"scripts": {
"vscode:prepublish": "npm run compile",
"compile": "tsc -p ./",
"watch": "tsc -watch -p ./"
},
"devDependencies": {
"@types/node": "^8.10.25",
"@types/vscode": "^1.51.0",
"tslint": "^5.16.0",
"typescript": "^3.4.5"
}
}
提示: 如果你的插件依赖 1.74 版本之前的 VS Code,你需要将
onCommand:helloworld.helloWorld
明确地列在activationEvents
中。
插件入口文件
插件入口文件导出两个方法,activate
和 deactivate
。activate
会在你注册的 激活事件 发生时执行。deactivate
会在你的插件停止运行之前执行,你可以在这时进行一些清理工作。对于大多数插件来说,清理工作并不是必要的,所以 deactivate
可以移除。然而,如果插件需要在 VS Code 关闭或者是插件被禁用时执行一些操作,deactivate
则是必要的。
VS Code API 的类型声明在 @types/vscode 中。vscode
的类型定义的版本被 package.json
中 engines.vscode
的值控制。当这个模块被激活,你就获得了智能类型提示、跳转到定义等 TypeScript 功能了。
// 'vscode' 模块包含了 VS Code 扩展 API
// 将这个模块包含在你的代码中
import * as vscode from 'vscode';
// 当你的插件被激活,这个方法会被立即调用
export function activate(context: vscode.ExtensionContext) {
// 使用控制台来输出信息(console.log)和错误(console.error)
// 这行代码只有在你的插件被激活时执行一次
console.log('Congratulations, your extension "helloworld-sample" is now active!');
// 这个命令在 package.json 中已经定义好了
// 现在使用 registerCommand 来提供这个命令的实现
// 命令 ID 必须和 package.json 中 command 字段匹配
let disposable = vscode.commands.registerCommand('helloworld.helloWorld', () => {
// 你在这里输入的代码将会在每次命令被执行时执行
// 向用户展示一个信息框
vscode.window.showInformationMessage('Hello World!');
});
context.subscriptions.push(disposable);
}
// 这个方法会在你的插件被关闭时执行
export function deactivate() {}