手把手教你打造 VS Code 插件 – wiki基地


手把手教你打造 VS Code 插件:从零开始掌握自定义开发利器

Visual Studio Code(VS Code)作为当下最流行的代码编辑器之一,其强大的功能、轻量级的体积以及卓越的性能赢得了无数开发者的青睐。然而,VS Code 的魅力远不止于此,它最核心的优势之一在于其高度的可扩展性。通过开发自定义插件(Extension),开发者可以根据自己的工作流程和需求,深度定制 VS Code,提升开发效率,打造属于自己的开发利器。

你是否曾经有过这样的想法:某个重复性的操作希望能一键完成?某种特定的文件格式需要更好的语法高亮或智能提示?或者想为某个项目集成一个自定义的工具链?如果是,那么开发一个 VS Code 插件或许就是最佳解决方案。

本篇文章将手把手带领你从零开始,一步步了解并实践如何创建一个属于你自己的 VS Code 插件。我们将覆盖从环境搭建、项目生成、代码编写、运行调试到最终打包发布的整个流程。

预计阅读时间较长,建议分段阅读并跟随操作。

1. 为什么需要开发 VS Code 插件?

VS Code 插件可以:

  • 自动化重复任务: 将繁琐的手动操作变成一键执行的命令。
  • 增强编辑体验: 提供自定义语法高亮、代码片段、格式化、智能提示等。
  • 集成外部工具或服务: 将 Linters、Debuggers、构建工具、云服务等直接集成到编辑器中。
  • 创建自定义 UI: 添加侧边栏视图、状态栏信息、Webview 等。
  • 提高团队协作效率: 分享自定义的工作流或代码规范检查工具。

掌握插件开发能力,意味着你不仅是 VS Code 的使用者,更能成为它的创造者,根据自己的需求塑造开发环境。

2. 前期准备:你需要具备的基础知识与工具

在开始之前,请确保你已经安装了以下工具和具备一些基础知识:

  • Node.js 和 npm (或 Yarn): VS Code 插件是基于 Node.js 开发和运行的。你需要安装 Node.js,其中包含了 npm 包管理器。建议安装 Node.js 的 LTS (长期支持) 版本。可以通过 node -vnpm -v 检查是否已安装成功。
  • Visual Studio Code: 这是我们开发和测试插件的平台。请确保安装了最新版本的 VS Code。
  • JavaScript 或 TypeScript 基础: VS Code 插件主要使用 JavaScript 或 TypeScript 进行开发。官方强烈推荐使用 TypeScript,因为它能提供更好的类型检查和代码提示,使得大型项目更易于维护。本教程也将主要使用 TypeScript。
  • 终端或命令行工具: 你需要使用终端来运行命令生成项目和打包。

3. 环境搭建:安装 Yeoman 和 Generator-Code

VS Code 官方提供了一个非常方便的脚手架工具 Yeoman 及其配套的 VS Code 插件生成器 generator-code,可以帮助我们快速创建插件项目的基础结构。

打开你的终端或命令行工具,运行以下命令全局安装 Yeoman 和 generator-code

bash
npm install -g yo generator-code

  • yo 是 Yeoman 的命令行工具。
  • generator-code 是专门用于生成 VS Code 插件项目的 Yeoman 生成器。

安装完成后,你就可以使用 yo code 命令来生成插件项目了。

4. 生成你的第一个插件项目

现在,我们来生成第一个 VS Code 插件项目。在终端中进入你希望创建项目的目录,然后运行:

bash
yo code

运行命令后,Yeoman 会启动交互式向导,询问你一些关于插件项目的问题。按照提示进行选择和填写:

  1. What type of extension do you want to create? (你想创建哪种类型的扩展?)

    • 选择 New Extension (TypeScript) (推荐使用 TypeScript)。
    • 如果你更熟悉 JavaScript,可以选择 New Extension (JavaScript)。本教程以 TypeScript 为例。
  2. What is the name of your extension? (你的扩展名称是什么?)

    • 输入一个简短、描述性的名称,例如 my-first-vscode-extension。这个名称会用作项目的文件夹名和 package.json 中的 name 字段。
  3. What is the identifier of your extension? (你的扩展标识符是什么?)

    • 这是插件的唯一 ID,通常与扩展名称相同,但建议使用小写字母和连字符,例如 my-first-vscode-extension
  4. What is the description of your extension? (你的扩展描述是什么?)

    • 输入一段简短的描述,例如 My first VS Code extension tutorial。这会在插件市场中显示。
  5. Initialize a Git repository? (初始化 Git 仓库?)

    • 通常选择 Yes (Y),方便版本控制。
  6. Bundle the extension? (打包扩展?)

    • 选择 Yes (Y)。这将配置 webpack 或 esbuild 等工具,将你的源代码打包成一个文件,优化加载速度。
  7. Which package manager to use? (使用哪个包管理器?)

    • 选择 npmyarn,取决于你的偏好。

回答完所有问题后,Yeoman 会在当前目录下创建一个新的文件夹(以你输入的扩展名称命名),并生成项目的基础文件和依赖。这个过程可能需要一些时间来下载 npm 包。

项目生成并依赖安装完成后,你就可以在 VS Code 中打开这个新创建的文件夹了。

5. 理解项目结构

打开项目文件夹后,你会看到类似以下的目录结构(如果选择了 TypeScript):

my-first-vscode-extension/
├── .vscode/ // VS Code 相关的配置文件,如调试配置 launch.json
├── src/
│ └── extension.ts // 插件的入口文件,核心逻辑在这里实现
├── package.json // 插件的清单文件,定义了插件的元数据、激活事件、贡献点等
├── tsconfig.json // TypeScript 配置文件
├── .gitignore // Git 忽略文件配置
├── .eslintrc.json // ESLint 配置 (如果选择安装)
├── webpack.config.js // Webpack 配置文件 (如果选择打包)
└── README.md // 项目说明文件

其中最重要的两个文件是:

  • package.json: 插件的“身份证”和“能力清单”。它包含了插件的名称、描述、版本、作者等元信息,更重要的是定义了插件在何时激活 (activationEvents) 以及为 VS Code 贡献了哪些功能 (contributes),例如命令、菜单项、快捷键、设置项、视图等等。
  • src/extension.ts: 插件的入口文件。这里包含了插件被激活时执行的代码 (activate 函数) 和插件被禁用时执行的代码 (deactivate 函数)。我们所有的插件逻辑都将从这里开始注册或实现。

6. package.json 详解:插件的配置中心

package.json 是 VS Code 插件开发中至关重要的文件,它定义了插件的各种行为和能力。我们来看一下生成项目后 package.json 中的一些关键字段:

json
{
"name": "my-first-vscode-extension",
"displayName": "My First VS Code Extension",
"description": "My first VS Code extension tutorial",
"version": "1.0.0",
"publisher": "yourpublishername", // 你的发布者名称,用于发布到市场
"engines": {
"vscode": "^1.80.0" // 你的插件兼容的最低 VS Code 版本
},
"categories": [
"Other" // 插件分类,用于市场检索
],
"activationEvents": [
"onCommand:my-first-vscode-extension.helloWorld" // 激活事件:当执行 helloWorld 命令时激活
],
"main": "./out/extension.js", // 插件的入口文件,通常是编译后的 JS 文件
"contributes": {
"commands": [
{
"command": "my-first-vscode-extension.helloWorld", // 命令的唯一 ID
"title": "Hello World" // 在命令面板中显示的名称
}
]
},
// ... 其他依赖、脚本等字段
}

  • name, displayName, description, version, publisher: 这些是插件的基本元信息。publisher 在你准备发布插件时需要注册和填写。
  • engines.vscode: 定义了插件所需的最低 VS Code 版本。确保你的 VS Code 版本符合要求。
  • categories: 插件在 VS Code Marketplace (市场) 中的分类,帮助用户更容易找到你的插件。
  • activationEvents: 激活事件。这是一个非常重要的字段,它告诉 VS Code 你的插件应该在什么时候被加载和激活。常见的激活事件包括:
    • onCommand:${commandId}: 当用户执行指定的命令时。这是最常用的激活方式,也是我们这次的示例。
    • onStartupFinished: 当 VS Code 启动完成后。应谨慎使用,如果插件启动耗时,会影响 VS Code 的启动速度。
    • workspaceContains:${fileName}: 当打开的文件夹包含指定名称的文件时。
    • onLanguage:${languageId}: 当打开指定语言类型的文件时(如 onLanguage:typescript)。
    • *: 任何时候都激活。极不推荐使用,除非你的插件必须从 VS Code 启动时就开始工作,因为它会显著增加 VS Code 的启动负担。
  • main: 指向插件的入口文件。对于 TypeScript 项目,这里通常指向编译后生成的 JavaScript 文件 (./out/extension.js)。
  • contributes: 贡献点。这是插件定义其功能的关键部分。它是一个对象,可以包含多个属性,每个属性代表一种贡献类型。
    • commands: 定义插件提供的命令。每个命令需要一个唯一的 command ID 和一个在命令面板中显示的 title

默认生成的 package.json 已经定义了一个名为 my-first-vscode-extension.helloWorld 的命令,其标题是 “Hello World”,并且设置了这个命令作为插件的激活事件。

7. extension.ts:实现插件的核心逻辑

src/extension.ts 是插件的入口文件,包含了 activatedeactivate 两个函数。

“`typescript
// The module ‘vscode’ contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
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
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 "my-first-vscode-extension" 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
let disposable = vscode.commands.registerCommand('my-first-vscode-extension.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 VS Code from my-first-vscode-extension!');
});

context.subscriptions.push(disposable);

}

// This method is called when your extension is deactivated
export function deactivate() {}
“`

  • import * as vscode from 'vscode';: 导入 VS Code 扩展 API。几乎所有与 VS Code 交互的功能都需要通过这个 vscode 对象来访问。
  • activate(context: vscode.ExtensionContext): 这个函数在插件被激活时执行(根据 package.json 中的 activationEvents 定义)。context 对象提供了访问扩展上下文的方法,例如 subscriptions (用于管理需要清理的资源) 和 extensionPath (插件的安装路径)。
  • deactivate(): 这个函数在插件被禁用时执行。可以在这里执行一些清理工作,例如关闭文件监听器、释放资源等。
  • console.log(...): 在 VS Code 的调试控制台输出信息。
  • vscode.commands.registerCommand(commandId, callback): 这是注册命令的关键 API。它需要两个参数:
    • commandId: 要注册的命令 ID,必须和 package.jsoncontributes.commands 里定义的 command 字段完全匹配。
    • callback: 一个函数,当用户执行该命令时,VS Code 会调用这个函数。
  • vscode.window.showInformationMessage(...): 这是 VS Code API 中的一个函数,用于在 VS Code 窗口的右下角显示一个信息提示框。这是我们第一个命令将要执行的操作。
  • context.subscriptions.push(disposable): registerCommand 函数会返回一个 Disposable 对象。我们需要将所有创建的 Disposable 对象(如注册的命令、事件监听器等)添加到 context.subscriptions 数组中。当插件被禁用时,VS Code 会自动遍历这个数组,调用每个 Disposable 对象的 dispose() 方法,从而清理资源,避免内存泄漏。这是一个非常重要的最佳实践!

默认生成的代码已经为我们注册了一个名为 my-first-vscode-extension.helloWorld 的命令,并在执行时弹出一个信息提示框。

8. 运行和调试你的插件

现在,我们来运行和测试刚刚生成的插件。

  1. 在 VS Code 中打开你的插件项目文件夹。
  2. 按下 F5 键,或者点击侧边栏的“运行和调试”图标,然后点击绿色的启动按钮。

按下 F5 后,VS Code 会执行以下操作:

  • 编译你的 TypeScript 代码 (如果使用 TypeScript)。
  • 在一个新的、独立的 VS Code 窗口中启动一个名为“Extension Development Host”(扩展开发宿主)的实例。这个新窗口是用来测试你的插件的。

在“Extension Development Host”窗口中:

  1. 按下 Ctrl+Shift+P (Windows/Linux) 或 Cmd+Shift+P (macOS) 打开命令面板。
  2. 开始输入你插件的命令标题,例如 Hello World。你会看到你的命令出现在列表中。
  3. 选择并执行 Hello World 命令。

如果一切顺利,你应该会在 VS Code 窗口的右下角看到一个提示框,显示 “Hello VS Code from my-first-vscode-extension!”。

同时,回到你开发插件的原始 VS Code 窗口,查看“调试控制台”面板。你应该会看到 console.log 输出的 “Congratulations, your extension…” 信息。

调试技巧:

  • extension.tsactivate 函数或命令回调函数内部设置断点(点击行号左边的区域)。
  • 在 Extension Development Host 窗口中执行命令,程序的执行会在原始 VS Code 窗口中设置的断点处暂停。
  • 你可以像调试普通 Node.js 程序一样,查看变量、单步执行代码等。

通过 F5 启动和调试是开发 VS Code 插件最常用的方式,它可以让你实时看到修改的效果并方便地定位问题。

9. 进阶:使用 VS Code API 丰富你的插件

“Hello World” 只是一个开始。VS Code 提供了丰富的 API,让你可以与编辑器、工作区、文件系统、用户界面等进行交互。以下是一些常用的 API 示例,你可以尝试将它们集成到你的命令回调函数中:

获取和修改编辑器内容:

“`typescript
// 获取当前活动文本编辑器
const editor = vscode.window.activeTextEditor;

if (editor) {
const document = editor.document;
const selection = editor.selection; // 获取当前选中范围

// 获取选中范围内的文本
const selectedText = document.getText(selection);
console.log(`当前选中的文本是: ${selectedText}`);

// 获取整个文档的文本
const fullText = document.getText();
console.log(`文档内容总共有 ${fullText.length} 个字符`);

// 在当前光标位置或选中区域插入文本
editor.edit(editBuilder => {
    editBuilder.insert(editor.selection.start, 'Hello, inserted text!'); // 在选中区域的起始位置插入
    // editBuilder.replace(selection, 'Replacement text'); // 替换选中区域的文本
    // editBuilder.delete(selection); // 删除选中区域的文本
});

// 移动光标或改变选中范围
const newPosition = new vscode.Position(selection.end.line, selection.end.character + 'Hello, inserted text!'.length);
editor.selection = new vscode.Selection(newPosition, newPosition); // 将光标移动到插入文本的末尾

} else {
vscode.window.showWarningMessage(‘请先打开一个文件!’);
}
“`

显示各种提示和输入框:

“`typescript
// 显示信息提示框
vscode.window.showInformationMessage(‘这是一个信息提示’);

// 显示警告提示框
vscode.window.showWarningMessage(‘这是一个警告!’);

// 显示错误提示框
vscode.window.showErrorMessage(‘出错了!’);

// 显示用户输入框
vscode.window.showInputBox({
prompt: ‘请输入一些文本’,
placeHolder: ‘例如:你的名字’
}).then(value => {
if (value !== undefined) { // 用户没有取消输入
vscode.window.showInformationMessage(你输入了: ${value});
}
});

// 显示快速选择框 (Quick Pick)
const options = [‘Option 1’, ‘Option 2’, ‘Option 3’];
vscode.window.showQuickPick(options, {
placeHolder: ‘请选择一个选项’
}).then(selection => {
if (selection) { // 用户进行了选择
vscode.window.showInformationMessage(你选择了: ${selection});
}
});
“`

创建和显示视图 (Views):

VS Code 支持在侧边栏、底部面板等位置创建自定义视图。这通常需要结合 package.jsoncontributes.viewscontributes.viewsContainers 贡献点,并在 extension.ts 中实现 vscode.TreeDataProvider 或其他视图提供者。这比简单的命令要复杂一些,需要查阅官方文档。

使用配置项 (Configuration):

你的插件可能需要一些用户自定义的设置。可以在 package.json 中使用 contributes.configuration 定义设置项,然后在 extension.ts 中使用 vscode.workspace.getConfiguration API 读取这些设置。

json
// package.json 中
"contributes": {
// ... 其他贡献点
"configuration": {
"title": "My Extension Configuration",
"properties": {
"myFirstExtension.mySetting": {
"type": "string",
"default": "default value",
"description": "这是一个自定义设置项的描述。"
},
"myFirstExtension.myBooleanSetting": {
"type": "boolean",
"default": true,
"description": "另一个布尔类型的设置。"
}
}
}
}

“`typescript
// extension.ts 中
const config = vscode.workspace.getConfiguration(‘myFirstExtension’); // 获取你的配置对象
const mySettingValue = config.get(‘mySetting’);
const myBooleanSettingValue = config.get(‘myBooleanSetting’);

console.log(mySetting的值是: ${mySettingValue});
console.log(myBooleanSetting的值是: ${myBooleanSettingValue});
“`

用户可以在 VS Code 的设置界面 (File -> Preferences -> SettingsCode -> Preferences -> Settings) 中搜索你的插件名称来修改这些设置。

注册快捷键 (Keybindings):

可以在 package.json 中使用 contributes.keybindings 为你的命令注册快捷键。

json
// package.json 中
"contributes": {
// ... 其他贡献点
"keybindings": [
{
"command": "my-first-vscode-extension.helloWorld",
"key": "cmd+alt+h", // macOS 上的快捷键
"mac": "cmd+alt+h",
"when": "editorTextFocus" // 快捷键生效的上下文,这里表示只有当编辑器有焦点时才生效
},
{
"command": "my-first-vscode-extension.helloWorld",
"key": "ctrl+alt+h", // Windows/Linux 上的快捷键
"linux": "ctrl+alt+h",
"win": "ctrl+alt+h",
"when": "editorTextFocus"
}
]
}

when 子句非常重要,它定义了快捷键在何种上下文环境下生效,避免与其他插件或 VS Code 自身的快捷键冲突。常用的上下文有 editorTextFocus (编辑器获得焦点时)、explorerResourceIsFolder (资源管理器选中项是文件夹时) 等。

通过灵活运用这些 API 和贡献点,你可以构建出功能强大、与 VS Code 无缝集成的自定义工具。

10. 打包你的插件 (.vsix 文件)

当你完成了插件的开发和测试,准备分享给其他人使用,或者想手动安装到其他 VS Code 实例时,你需要将插件打包成一个 .vsix 文件。

首先,确保你已经安装了 vsce (VS Code Extension Manager) 工具:

bash
npm install -g vsce

然后,在你的插件项目根目录下(与 package.json 文件同级),运行打包命令:

bash
vsce package

如果你的 package.json 中没有填写 publisher 字段,vsce 可能会提示你填写或使用默认值。为了发布到市场,publisher 必须是你注册过的。即使只是打包用于本地安装,也建议填写一个唯一的发布者名称。

vsce package 命令会执行以下操作:

  • 运行 npm install --production 安装生产环境依赖。
  • 运行 npm run vscode:prepublish 脚本 (如果 package.json 中定义了)。对于 TypeScript 项目,这个脚本通常用于编译 .ts 文件到 .js
  • 收集必要的文件 (代码、package.jsonREADME.mdCHANGELOG.mdLICENSE 等)。
  • 将这些文件打包成一个 .vsix 后缀的文件,文件通常命名为 your-extension-id-version.vsix,例如 my-first-vscode-extension-1.0.0.vsix

打包成功后,你会在项目根目录下找到生成的 .vsix 文件。

安装 .vsix 文件:

要手动安装 .vsix 文件,打开 VS Code,点击侧边栏的“扩展”图标,然后点击扩展视图右上角的“…”(更多操作)菜单,选择“从 VSIX 安装…”,然后选择你生成的 .vsix 文件即可。

11. 发布你的插件到 VS Code Marketplace

如果你想让全世界的 VS Code 用户都能方便地找到并安装你的插件,你可以将其发布到官方的 VS Code Marketplace。

发布过程需要几个步骤:

  1. 注册 Azure DevOps 组织: VS Code Marketplace 使用 Azure DevOps 作为身份验证和发布平台。你需要创建一个 Azure DevOps 组织(如果还没有的话)。
  2. 创建发布者 (Publisher): 在 Azure DevOps 中创建一个 Publisher。这个 Publisher 名称将用于你的插件 ID (publisher.extensionName),并显示在插件市场的页面上。
  3. 创建个人访问令牌 (Personal Access Token – PAT): 在 Azure DevOps 中为你的 Publisher 创建一个 PAT,用于 vsce 工具进行身份验证和发布。PAT 需要有 Marketplace (Publish) 的权限。
  4. 登录 vsce 在终端中运行 vsce login <publisher-name>,按照提示输入你刚刚创建的 PAT。vsce 会将你的登录信息存储在本地。
  5. 发布: 在你的插件项目根目录下,运行发布命令:

    bash
    vsce publish

    vsce 会执行打包过程,然后将 .vsix 文件上传到 Marketplace。

    如果这是你第一次发布这个插件,它会被创建;如果之前已经发布过,它会更新到新的版本(请确保你在 package.json 中更新了 version)。

发布成功后,你的插件将会在 Marketplace 网站上可见,并在 VS Code 的扩展面板中可以搜索到。这个过程可能需要几分钟到几小时不等。

详细的发布指南请参考 VS Code 官方文档:Publishing Extensions

12. 插件开发的小贴士和资源

  • 查阅官方文档: VS Code 扩展 API 文档是你的最佳伙伴。它详细介绍了所有可用的 API 和贡献点,以及如何使用它们:VS Code Extension API
  • 学习其他插件的源码: GitHub 上有大量的开源 VS Code 插件,阅读它们的源代码是学习高级技巧和最佳实践的好方法。
  • 使用 TypeScript: 强烈建议使用 TypeScript。它带来的类型安全和代码提示能显著提高开发效率和代码质量。
  • 谨慎选择激活事件 (activationEvents): 只在真正需要时激活你的插件,避免使用 *,这有助于保持 VS Code 的启动速度和整体性能。
  • 使用 context.subscriptions 管理资源: 将所有 Disposable 对象添加到 context.subscriptions 中,确保插件禁用时资源得到清理。
  • 编写单元测试: 为你的插件逻辑编写单元测试,保证代码的质量和稳定性。generator-code 生成的项目已经包含了测试框架的配置。
  • 提供清晰的 README.md: 详细说明你的插件功能、安装方法、使用说明、配置选项等信息,方便用户了解和使用。

13. 总结

通过本篇文章,我们手把手学习了如何使用 Yeoman 和 generator-code 创建一个基础的 VS Code 插件项目,理解了 package.jsonextension.ts 这两个核心文件,掌握了如何定义和实现一个简单的命令,以及如何在 Extension Development Host 中运行和调试插件。此外,我们还初步了解了如何利用 VS Code API 与编辑器进行交互,以及如何打包和发布你的插件。

这仅仅是 VS Code 插件开发的冰山一角。VS Code 提供了非常灵活和强大的扩展机制,你可以开发各种类型的插件,从简单的命令工具到复杂的语言支持、调试器集成等。

现在,你已经具备了开发 VS Code 插件的基础能力。接下来,挑战自己,根据你的实际需求,尝试构建更复杂的插件吧!记住,官方文档永远是你最可靠的参考资料。

祝你在 VS Code 插件开发的旅程中创造出令人惊艳的工具!

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部