你的第一个扩展
在本主题中,我们将教你构建扩展的基本概念。确保你已安装 Node.js 和 Git。
首先,使用 Yeoman 和 VS Code 扩展生成器搭建一个准备好进行开发的 TypeScript 或 JavaScript 项目。
- 如果你不想为以后使用安装 Yeoman,请运行以下命令:
npx --package yo --package generator-code -- yo code - 如果你想全局安装 Yeoman 以便于重复运行,请运行以下命令:
npm install --global yo generator-code
yo code 对于 TypeScript 项目,填写以下字段:
_-----_ ╭──────────────────────────╮
| | │ Welcome to the Visual │
|--(o)--| │ Studio Code Extension │
`---------´ │ generator! │
( _´U`_ ) ╰──────────────────────────╯
/___A___\ /
| ~ |
__'.___.'__
´ ` |° ´ Y `
? What type of extension do you want to create? New Extension (TypeScript)
? What's the name of your extension? HelloWorld
? What's the identifier of your extension? helloworld
? What's the description of your extension?
? Initialize a git repository? Yes
? Which bundler to use? unbundled
? Which package manager to use? pnpm在编辑器中,打开 src/extension.ts 并按 F5 或从命令面板运行 Debug: Start Debugging 命令(⇧⌘P (Windows, Linux Ctrl+Shift+P))。这将编译扩展并在新的 扩展开发宿主 窗口中运行它。
在新窗口中从命令面板(⇧⌘P (Windows, Linux Ctrl+Shift+P))运行 Hello World 命令:
你应该会看到 Hello World from HelloWorld! 通知显示出来。成功!
如果你在调试窗口中看不到 Hello World 命令,请检查 package.json 文件并确保 engines.vscode 版本与已安装的 VS Code 版本兼容。
开发扩展
让我们对消息进行修改:
- 在
extension.ts中将消息从 “Hello World from HelloWorld!” 更改为 “Hello VS Code”。 - 在新窗口中运行 Developer: Reload Window。
- 再次运行 Hello World 命令。
你应该会看到更新后的消息显示出来。
以下是一些你可以尝试的想法:
- 在命令面板中为 Hello World 命令提供一个新名称。
- 贡献另一个在信息消息中显示当前时间的命令。贡献点是你在
package.json扩展清单中做出的静态声明,用于扩展 VS Code,例如向你的扩展添加命令、菜单或键绑定。 - 用另一个 VS Code API 调用替换
vscode.window.showInformationMessage以显示警告消息。
调试扩展
VS Code 的内置调试功能使调试扩展变得容易。通过点击行旁边的装订线设置断点,VS Code 将命中断点。你可以在编辑器中悬停在变量上或使用左侧的 运行和调试 视图来检查变量的值。调试控制台允许你评估表达式。
你可以在 Node.js 调试主题中了解更多关于在 VS Code 中调试 Node.js 应用的信息。
下一步
在下一个主题”扩展剖析”中,我们将仔细查看 Hello World 示例的源代码并解释关键概念。
你可以在以下位置找到本教程的源代码:helloworld-sample。扩展指南主题包含其他示例,每个示例都展示了不同的 VS Code API 或贡献点,并遵循我们的 UX 指南中的建议。
使用 JavaScript
在本指南中,我们主要描述如何使用 TypeScript 开发 VS Code 扩展,因为我们认为 TypeScript 为开发 VS Code 扩展提供了最佳体验。然而,如果你更喜欢 JavaScript,你仍然可以使用 helloworld-minimal-sample 跟随学习。
UX 指南
现在也是查看我们的 UX 指南的好时机,这样你就可以开始设计你的扩展用户界面,遵循 VS Code 最佳实践。
扩展剖析
在上一个主题中,你已经能够运行一个基本的扩展。它在底层是如何工作的呢?
Hello World 扩展做了3件事:
- 注册 onCommand 激活事件:
onCommand:helloworld.helloWorld,这样当用户运行Hello World命令时扩展就会被激活。
注意: 从 VS Code 1.74.0 开始,在
package.json的commands部分声明的命令会在调用时自动激活扩展,而不需要在activationEvents中显式添加onCommand条目。
- 使用 contributes.commands 贡献点 使
Hello World命令在命令面板中可用,并将其绑定到命令IDhelloworld.helloWorld。 - 使用 commands.registerCommand VS Code API 将一个函数绑定到已注册的命令ID
helloworld.helloWorld。
理解这三个概念对于在 VS Code 中编写扩展至关重要:
- 激活事件:使你的扩展变为活动状态的事件。
- 贡献点:你在
package.json扩展清单中声明的静态声明,用于扩展 VS Code。 - VS Code API:一组你可以在扩展代码中调用的 JavaScript API。
一般来说,你的扩展会使用贡献点和 VS Code API 的组合来扩展 VS Code 的功能。扩展功能概述主题可以帮助你为扩展找到合适的贡献点和 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:激活事件和贡献点。engines.vscode:这指定了扩展所依赖的 VS Code API 的最低版本。
{
"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 版本,则必须在
activationEvents中明确列出onCommand:helloworld.helloWorld。
扩展入口文件
扩展入口文件导出两个函数,activate 和 deactivate。activate 在你注册的激活事件发生时执行。deactivate 给你一个机会在扩展被停用前进行清理。对于许多扩展,可能不需要明确的清理,可以删除 deactivate 方法。但是,如果扩展在 VS Code 关闭或扩展被禁用或卸载时需要执行操作,这是执行该操作的方法。
VS Code 扩展 API 在 @types/vscode 类型定义中声明。vscode 类型定义的版本由 package.json 中 engines.vscode 字段的值控制。vscode 类型为你的代码提供 IntelliSense、转到定义和其他 TypeScript 语言功能。
// 模块 'vscode' 包含 VS Code 扩展 API
// 导入模块并在下面的代码中使用别名 vscode 引用它
import * as vscode from 'vscode';
// 当你的扩展被激活时调用此方法
// 你的扩展在第一次执行命令时被激活
export function activate(context: vscode.ExtensionContext) {
// 使用控制台输出诊断信息(console.log)和错误(console.error)
// 这行代码只会在你的扩展被激活时执行一次
console.log('恭喜,你的扩展 "helloworld-sample" 现在已激活!');
// 命令已在 package.json 文件中定义
// 现在使用 registerCommand 提供命令的实现
// commandId 参数必须与 package.json 中的 command 字段匹配
let disposable = vscode.commands.registerCommand('helloworld.helloWorld', () => {
// 你在这里放置的代码将在每次执行命令时执行
// 向用户显示消息框
vscode.window.showInformationMessage('Hello World!');
});
context.subscriptions.push(disposable);
}
// 当你的扩展被停用时调用此方法
export function deactivate() {}