从0到1实现一个属于自己的VScode插件
VScode是微软推出的一款轻量级代码编辑器,也是前端开发中常用的编辑器,其设计思想就是拓展性,VScode的大部分功能都可以自定义实现,通过 Extension API
扩展实现,很多VScode的核心功能就是这样实现的,我们自然也可以利用VScode开放API进行扩展功能的开发,从而解决我们日常开发中的一些问题,提高开发效率。 通过本文讲解,我们可以快速了解如何开发一个VS Code插件,实际操作起来还是挺简单的,遇到不熟悉或者疑问之处可以查看官方文档,文档内容写的十分全面。
文章内容若有不足,欢迎指正。
1. VScode插件是什么?
VScode是微软推出的一款轻量级代码编辑器,免费、开源而且功能强大,也是前端开发中常用的编辑器,我们作为一个前端开发者,对于此编辑器自然不陌生。在使用时我们经常会安装一些插件来协助我们进行开发,这些插件就是利用VScode给我们提供的一些开放的API的基础上进行扩展功能的开发,从而解决我们日常开发中的一些问题,提高开发效率。VScode 插件其实就是类似于一个npm包的vsix
文件。

vscode插件开发的官方文档为:code.visualstudio.com/api
2. VScode插件可以做什么?
VScode插件几乎可以自定义我们的VScode编辑器的任意功能,例如:
- 自定义命令、快捷键、菜单;
- 自定义跳转、自动补全、悬浮提示
- 自定义颜色、图标主题
- 代码高亮、语法高亮、检查、格式化等
- 扩展工作台
- 编辑器相关(修改编辑器语言、通知、状态栏等)
- git 功能页面可视化
- 。。。。。。
3. 如何创建一个属于自己的插件
上文已经简单阐述了 VScode插件是什么以及可以做什么,下面我们就来实际操作一下,做一个行动上巨人。
3.1 环境搭建
微软官方给我们提供了脚手架,通过这个脚手架我们可以快速的搭建一个简单的VScode插件。
因为npm官网安装依赖可能会有点慢,也可能安装失败,所以推荐使用阿里或腾讯镜像源仓库,具体配置命令如下:
arduino
// 设置依赖安装镜像源为淘宝镜像源(使用者较多,推荐)
npm config set registry https://registry.npmmirror.com/
// 设置依赖安装镜像源为腾讯内部镜像源(不需要腾讯内网也能正常访问)
npm config set registry https://mirrors.tencent.com/npm/
通过执行下方命令安装微软官方脚手架:
css
npm i -g yo generator-code
上述命令其实安装了两个包(yo和generator-code),这两个包用途如下:
-
yo模块全局安装后就安装了Yeoman,Yeoman是通用型项目脚手架工具,可以根据一套模板,生成一个对应的项目结构
-
generator-code模块是VS Code扩展生成器,与yo配合使用才能构建项目。
上述命令执行后出现如下页面表示安装成功,可以继续执行后续操作

3.2 使用脚手架搭建一个基础的VScode插件模版
在本地的工作目录中执行下方命令使用脚手架创建插件模版项目
css
yo code
创建项目会开启一个交互命令行,需要先选择插件类型,控制键盘的方向键的上下来决定选择什么类型,按 Enter 键确认

根据自己的实际需求来选择你想创建的插件类型,目前支持以下几种类型:
-
New Extension (TypeScript) :ts 语法的项目,基础版,内置了hello world的命令
-
New Extension (JavaScript) : js 语法的项目,基础版,内置了hello world的命令
-
New Color Theme :主题项目,内置了主题,可用来自定义主题
-
New Language Support:语言支持项目,内置了语法支持配置,可用来支持特殊语言
-
New Code Snippets:代码片段项目,内置了代码片段配置,可用来配置代码片段,输入触发字符,快速生成代码片段
-
New Keymap:快捷键项目,内置了快捷键配置,可用来自定义快捷键行为
-
New Extension Pack:插件集合项目,内置了插件集合配置,可用于定制插件集,达到快速安装一组插件
-
New Language Pack (Localization):目前官方文档暂未查到localizations贡献的场景点
-
New Web Extension (TypeScript) : ts语法的项目, 在 VS Code for Web (包括vscode.dev和github.dev) 以及桌面和GitHub Codespaces等服务将支持该扩展
-
New Web Extension (JavaScript) : js 语法的项目,在 VS Code for Web (包括vscode.dev和github.dev) 以及桌面和GitHub Codespaces等服务将支持该扩展
web扩展可参考官方文档链接 code.visualstudio.com/api/extensi...
使用脚手架创建模版项目步骤详解如下图所示:
注意:插件名必须全小写,且不能有空格
选择不同的插件类型时,下方交互命令行选择填写的条例不同,此处仅以创建一个ts模版项目和创建一个快捷键项目为例,其他的插件类型的大同小异,都是一些前端开发中使用到的配置,看一下就知道要怎么选择了。
- 使用脚手架创建一个ts的模版项目

- 使用脚手架创建一个插件类型为快捷键模版项目

3.3 package.json文件详解
字段名 | 说明 |
---|---|
name | 插件名(要求全小写,无空格) |
displayName | 发布到 VS Code 应用市场名称 |
version | 插件版本 |
publisher | 发布者 |
engines | vscode或其他环境依赖版本的要求 |
categories | 扩展类别 |
contributes | 插件贡献点,比如命令、快捷键、菜单等 |
activationEvents | 插件触发动作,如在打开某种语言的文件时、当某个命令被触发时 |

执行命令后生成的模板项目的package.json文件如下:
json
{
"name": "ggg-test",
"displayName": "ggg-test",
"description": "哈哈哈哈,一个小demo",
"version": "0.0.1",
"engines": {
"vscode": "^1.85.0"
},
"categories": [
"Other"
],
"activationEvents": [],
"main": "./dist/extension.js",
"contributes": {
"commands": [
{
"command": "ggg-test.helloWorld",
"title": "Hello World"
}
]
}
}
3.3.1 activationEvents 配置项详解
activationEvents 配置项配置插件的激活数组,即在什么情况下插件会被激活,目前支持以下8种配置:
-
onLanguage: 当打开解析为某种语言的文件时触发
-
onCommand: 当调用对应命令时触发
-
onDebug: 在 debug 调试会话开始前,将发出此激活事件并激活感兴趣的扩展
-
onDebugInitialConfigurations: 在 debug 初始化配置之前触发
-
onDebugResolve: 在 debug 设置处理完之前触发
-
workspaceContains: 当打开文件夹并且该文件夹至少包含一个与glob 模式匹配的文件时触发
-
onFileSystem:当读取特定类型或协议中的文件或文件夹时触发
-
onView: 每当 VS Code 侧边栏中展开指定 id 的视图时触发,并激活感兴趣的扩展(扩展或源代码管理是内置视图的示例)
-
onUri: 在基于 vscode 或 vscode-insiders 协议的 url 打开时触发
-
onWebviewPanel: 每当 VS Code 需要恢复具有匹配的webview时触发,并且将激活感兴趣的扩展 viewType
-
onCustomEditor: 需要创建具有匹配的自定义编辑器时触发
-
onAuthenticationRequest: 当扩展请求具有匹配的身份验证会话(通过 API)时触发。注意:从 VS Code 1.74.0 开始,您的扩展提供的身份验证提供程序不需要相应的onAuthenticationRequest激活事件声明来激活您的扩展。
-
onStartupFinished: 在VS Code 启动后一段时间触发,类似于 * ,但不会减慢 VS Code 的启动速度,
-
*: 在启动 VS Code 时触发,为了保证良好的用户体验,非必须情况下不建议使用此配置
注意:一个扩展可以监听多个激活事件
注意:扩展 必须
activate()
从其主模块导出一个函数,并且当发出任何指定的激活事件时,VS Code 仅会调用该函数一次
。此外,扩展应该 deactivate()
从其主模块导出一个函数,以便在 VS Code 关闭时执行清理任务。如果清理过程是异步的,则扩展必须返回 Promise 。如果清理同步运行,则 deactivate()
扩展可能会返回 undefined
。deactivate()
3.3.2 contributes(贡献点)配置详解
contributes 配置项是整个插件的贡献点,表明这个插件有什么功能。
-
breakpoints: 断点
-
colors: 主题颜色
-
commands: 命令,通过 control + shift + p 打开命令窗口进行输入来实现的。
-
configuration: 通过这个配置项我们可以设置一个属性,这个属性可以在vscode的settings.json中设置,然后在插件工程中可以读取用户设置的这个值,进行相应的逻辑。
-
configurationDefaults: 配置可以在 setting.json 文件中配置的字段
-
customEditors: 自定义编辑器
-
debuggers: 提供一个调试器
-
grammars: 可以在这个配置项里设置描述语言的语法文件的路径,vscode可以根据这个语法文件来自动实现语法高亮功能
-
icons: 按 ID 提供新图标以及默认图标
-
iconThemes: icon主题色
-
jsonValidation: 为特定类型的 json 文件提供验证架构
-
keybindings: 快捷键绑定
-
languages: 设置语言特点,包括语言的后缀等
-
menus: 自定义编辑器菜单,包括右键菜单、头部菜单等
-
problemMatchers: 问题匹配器模式
-
problemPatterns: 问题匹配器中使用的命名问题模式
-
productIconThemes: 产品图标主题
-
resourceLabelFormatters: 资源标签格式化程序,指定如何在工作台中的任何位置显示 URI
-
semanticTokenModifiers: 新的语义标记修饰符,可以通过主题规则突出显示
-
semanticTokenScopes: 语义标记类型和修饰符以及范围之间的映射,作为后备或支持特定于语言的主题
-
semanticTokenTypes: 可以通过主题规则突出显示的新语义标记类型
-
snippets 特定语言的片段,设置语法片段相关的路径
-
submenus: 子菜单作为可以贡献菜单项的占位符,子菜单要求在父菜单中显示 label
-
taskDefinitions: 定义一个对象文字结构,该结构允许唯一地标识系统中的贡献任务
-
terminal: 终端
-
themes 颜色主题
-
typescriptServerPlugins: 提供 TypeScript 服务器插件,增强 VS Code 的 JavaScript 和 TypeScript 支持
-
views: 配置活动栏对应的view视图
-
viewsContainers: 可以贡献自定义视图的视图容器
-
viewsWelcome: 引导页,向自定义视图贡献欢迎内容
-
walkthroughs: 演练由标题、描述、ID 和一系列步骤组成。此外,还可以设置 when 条件来根据上下文键隐藏或显示演练。
3.4 extension.js文件详解
extension.js
是插件工程的入口文件,即 package.json
中main
字段对应的文件(文件名可根据自己需要更改,只需要保证和package.json中main字段对应即可),当插件被激活,即触发package.json
中的activationEvents
配置项时,extension.js
文件开始执行。
extension.js
文件将导出两个方法:activate
和deactivate
,其执行时机如下所示:
-
activate: 插件被激活时执行的函数
-
deactivate: 插件被销毁时调用的方法,比如释放内存等
在 extension.js
中对需要的功能进行注册,主要使用vscode.commands.register...
相关的api,来为package.json
中的contributes
配置项中的事件绑定方法或者监听器。 vscode.commands.register...
相关的api主要有:
-
vscode.commands.registerCommand() 注册命令
-
vscode.languages.registerCompletionItemProvider() 代码补全
-
vscode.languages.registerCodeActionsProvider() 注册一个代码操作提供者
-
vscode.languages.registerCodeLensProvider()
-
vscode.languages.registerHoverProvider() 代码悬浮提示
vscode.commands.registerCommand
用于注册命令,ggg-test.helloWorld
为命令ID,需要与 package.json
文件中的 contributes.commands
数组中的 command
后的配置一致,第二个参数为一个回调函数,当触发该命令时,弹出提示框。
执行命令后生成的模板项目的extension.js文件如下:
javascript
// 引入 vscode 核心库,提供了开发插件所需的大部分 api
import * as vscode from 'vscode';
// 当插件被激活触发
export async function activate(context: vscode.ExtensionContext) {
console.log('Congratulations, your extension "ggg-test" is now active!');
// 调用vscode注册命令API,注册了一个名(命令唯一标识)为 ggg-test.helloWorld的命令
// 注意,此处注册的命令必须和 package.json文件中的 contributes.commands数组中的 command 命令配置的一致
let disposable = vscode.commands.registerCommand('ggg-test.helloWorld', () => {
// 执行命令,会在右下角展示提示信息
vscode.window.showInformationMessage('Hello World from ggg-test!');
});
// 事件入栈
context.subscriptions.push(disposable);
}
// 当插件停用时触发
export function deactivate() {}
3.4.1 写一个简单的小弹窗提示
extension.js文件如下:
javascript
// 引入 vscode 核心库,提供了开发插件所需的大部分 api
import * as vscode from 'vscode';
// 引入 node 中的 os 模块,下面使用 platform 方法获取系统
import * as os from 'os';
import { exec } from 'child_process';
// 当插件被激活触发
export async function activate(context: vscode.ExtensionContext) {
console.log('Congratulations, your extension "ggg-test" is now active!');
const key = 'sweetheartPlugin.showTip';
const showTip = vscode.workspace.getConfiguration().get(key);
if (showTip) {
const result = await vscode.window.showInformationMessage('是否要打开作者个人网页?', '是', '否', '不再提示');
if (result === '是') {
const commandOperation = os.platform() === 'win32' ? `start https://sweetheartjq.cn/` : `open https://sweetheartjq.cn/`;
exec(commandOperation);
} else if (result === '不再提示') {
//最后一个参数,为true时表示写入全局配置,为false或不传时则只写入工作区配置
await vscode.workspace.getConfiguration().update(key, false, true);
}
}
// 调用vscode注册命令API,注册了一个名(命令唯一标识)为 ggg-test.helloWorld的命令
// 注意,此处注册的命令必须和 package.json文件中的 contributes.commands数组中的 command 命令配置的一致
let disposable = vscode.commands.registerCommand('ggg-test.helloWorld', () => {
// 执行命令,会在右下角展示提示信息
vscode.window.showInformationMessage('Hello World from ggg-test!');
});
// 事件入栈
context.subscriptions.push(disposable);
}
// 当插件停用时触发
export function deactivate() {}
package.json文件如下:
json
{
"name": "ggg-test",
"displayName": "ggg-test",
"description": "哈哈哈哈,一个小demo",
"version": "0.0.1",
"engines": {
"vscode": "^1.85.0"
},
"categories": [
"Other"
],
"activationEvents": [],
"main": "./dist/extension.js",
"contributes": {
"commands": [
{
"command": "ggg-test.helloWorld",
"title": "Hello World"
}
],
"configuration": {
"title": "sweetheart-plugin",
"properties": {
"sweetheartPlugin.showTip": {
"type": "boolean",
"default": true,
"description": "是否在每次启动时显示提示?"
}
}
}
}
}
3.5 VScode插件生命周期
VSCode的插件都运行在一个独立的进程里, 被称为 Extension Host, 它加载并运行插件, 让插件感觉自己好像在主进程里一样, 同时又严格限制插件的响应时间, 避免插件影响主界面进程。

-
1.
activationEvents
:在package.json
的activationEvents
配置项中设置插件激活时机,这里设置的是onCommand:ggg-test.helloWorld
,即输入命令onCommand:ggg-test.helloWorld
时激活。 -
2.
contributes
:package.json
中的contributes
配置项表示这个插件增加了哪些功能,这里设置了commands
,表示增加的命令,在这一项中声明了一个命令ggg-test.helloWorld
。 -
3.
Register
:在extension.js
文件中的activate(context)
方法中,使用vscode.commands.registerCommand
()这一API为命令ggg-test.helloWorld
绑定事件,绑定的事件为vscode.window.showInformationMessage('Hello World from ggg-test!')
,即弹出弹框,显示Hello World from ggg-test!
。 -
4.在命令框中输入
ggg-test.helloWorld
,此时插件被激活,进入extension.js
中执行activate()
方法,由于已经在contributes
配置项中声明了命令ggg-test.helloWorld
,所以在activate()
方法中为该命令绑定一个事件,由于在命令框中输入了这个命令,所以命令绑定的事件立即被触发执行,所以在vscode的右下角弹出了弹出框。
3.6 发布插件到 VS Code 拓展商店
-
- 在本地安装 vsce(Visual Studio Code Extension)依赖
css
npm i -g vsce
-
- VS Code 使用
Azure DevOps
作为其 Marketplace 服务。所以需要登录一下Azure
。登录后,如果之前没用过的话会要求创建一个组织,默认为邮箱前缀, Azure 网址,在 Azure上获取一个 access token ,在下面创建发布者时需要用到
- VS Code 使用


-
- 创建一个发布者
scss
vsce create-publisher (publisher name)
// publisher name 为 package.json 中的 publisher字段的值
// 执行后,会让输入 Personal Access Tokens
// 将上面创建好的 Personal Access Tokens 输入
-
- 登录刚才创建的发布者
java
vsce login (publisher name)
-
- 打包
go
vsce package
-
- 发布
vsce publish
4. 实现一个格式化 git Commit message 的插件
在我们的日常开发中,git
相关操作是每天都要接触的,属于一个高频操作,我们或许会使用以下方式来提交我们的代码
-
git 原生命令
-
WebStorm 或 VS code 自带git工具
-
类似于
sourceTree
之类的第三方工具 -
......
但根据不同公司的不同业务场景,代码提交格式也有不同的规范,我们手动操作不可避免的会出现问题,此时一个可以帮助我们搞定git 提交信息的插件就显得尤为重要了。
4.1 效果展示

4.2 插件获取
- 插件目前已发布到 VS Code 插件应用市场,可通过在扩展商店中直接搜索
devops-commitizen
获取

- 可在 VS Code官方应用市场下载安装
marketplace.visualstudio.com/items?itemN...
- 可通过github仓库下载打包之后的
vsix
文件,目前最新版本为V1.1.1
,但vsix
文件不能直接拖入安装,只能从扩展的右上角选择Install from VSIX
来安装,github地址可在下方获取

4.3 代码获取
格式化 git Commit message 插件devops-commitizen
代码已在github开源,有需要源码参考的可下载查看,若有不足之处,欢迎指正。