笔者从业以来,各路插件开发无算,而 vscode 把插件开发体验做到了极致。其开发体验,如沐春风,如丝般顺滑,经常写完了还想删掉再写一遍!
vscode 扩展的内置脚手架细心且精致,一键生成后即可运行。vscode 库类型完美,因此开发者可以仅通过 IDE 提示来猜到 API,省去了很多文档查阅成本。最后,vscode 扩展开发文档丰富、开发体系清晰。
废话少说,让我们进入正题吧。
认识 vscode
vscode 扩展设计理念
1、extension host
vscode 扩展运行进程与 vscode 主进程互相独立,以避免有 bug 的扩展阻塞 vscode 主进程运行。
2、activation events
为保证 vscode 性能。所有 vscode 扩展都是按需加载的。每个扩展应该声明加载时机,常用的声明方式如下:
-
onLanguage:python 当用户打开 python 代码文件时。`
-
onCommand:sayHello 当用户执行 sayHello 命令时。 command 的概念稍后介绍。
-
workspaceContains:pont-config.json 当项目中包含 pont-config.json 文件时。
-
* 一直打开,不推荐。
3、vscode UI 组件
vscode UI 组件非常简洁,也几乎没有可扩展性。这个设计,意在引导扩展开发者保持扩展 UI 的简洁和视觉风格统一。
当然,如果你执意要自定义组件,则可以调用 createWebviewPanel API,自定义 html、css、js 组成一个 iframe,来完全自定义一个 UI 组件。
manifest
任何插件系统都需要一个 manifest 文件,来声明插件相关的元信息,vscode 也不例外。
vscode 的 manifest 文件内置在 package.json 中。下面介绍 package.json 中属于 vscode manifest 部分的字段。
1、Contribution Points
一个 vscode 扩展除了可以增强 vscode 的功能,还可以提供自定义 snippets、theme、快捷键、配置集,而这些都可以通过
contributes
字段来支持。
contributes
字段用得比较多的有
configuration
、
commands
、
keybindings
、
snippets
、
jsonValidation
等。下面一一介绍:
1)、configuration
自定义你扩展的配置项。你可以在扩展中通过如下命令获取用户的配置值:
vscode.workspace.getConfiguration('myExtension');
示例:
{
"contributes": {
"configuration": {
"type": "object",
"title": "TypeScript configuration",
"properties": {
"typescript.tsdk": {
"type": ["string", "null"],
"default": null,
"description": "Specifies the folder path containing the tsserver and lib*.d.ts files to use."
}
}
}
}
}
2)、commands
在 vscode 中,cmd + p 可以打命令面板,你可以在此执行所有的命令。vscode 中所有行为都会被定义为命令,然后在菜单项行为、快捷键行为定义中引用该命令。
3)、keybindings
定义快捷键和它对应的 command。
4)、snippets
定义并提供 snippets(代码片段)
5)、jsonValidation
有没有记得,你在编辑 tsconfig.json 等配置文件的时候,vscode 有充分的补全和属性提示?这个功能可以通过定义一份配置文件对应的 json schema 来提供。
官方文档
示例介绍
以
vscode-pont
(vscode-pont 是一个智能接口代码生成器,下期笔者会详细介绍)为例。package.json 文件的 contributes 中,定义了 jsonValidation,使 vscode-pont 的配置文件 pont-config.json 编辑智能化。另外定义了一个快捷键,及其对应的命令。
vscode 扩展开发实践
vscode 扩展一般用 Typescript 开发,其完整、健全的类型系统,可以让你几乎不用看文档完成插件开发。扩展开发可以使用 vscode API 和 node API ,你也可以用 npm 包的方式使用任意依赖。你也可以用 Web API 来写自定义组件。
1、Yo Code - 脚手架安装
安装命令如下:
npm install -g yo generator-code yo code
如下图所示:
2、填写扩展基本信息
yo 会提示你填写扩展项目的基本信息,如项目名、项目id、描述、发布人,是否初始化git等。按部就班填写即可。如下图所示:
3、运行和调试
yo 会初始化一个 hello world 的扩展,点击运行查看效果。
插件运行后,会新开一个 vscode 窗口,你可以在此验证你的扩展效果,也可以在源码中一步步调试。
4、进阶
接下来,我们将基于 hello-world,做一个显示你打开代码的注释率的扩展 —— 让 vscode 状态栏显示当前代码的注释率。
1)、更新 activationEvents
package.json 中更新 activationEvents 属性。定义插件的加载时机。
如下所示,当在 vscode 打开 tsx 和 ts 代码时,则加载当前扩展。
"activationEvents": [ "onLanguage:typescript", "onLanguage:typescriptreact" ],
2)、定义 UI 层
vscode 库类型和注释完美,大多数时候,我们通过 vscode 的智能提示,就能找到我们想要的 API。 我们先了解一下 vscode 下一些常用的命名空间:
-
workspace 当前工作区相关,文件树相关 API。
-
window 当前视窗相关,编辑器相关 API。
-
commands 注册 command 。
然后在 vscode 这些命名空间中探索其 API,得到如下 UI 层代码:
// 如果目前存在打开的代码 Tab 页。
if (vscode.window.activeTextEditor) {
// 展示注释率
showRate(vscode.window.activeTextEditor);
}
// 如果当前切换了代码 Tab 页,则重新计算注释率
vscode.window.onDidChangeActiveTextEditor(showRate);
状态栏展示代码注释率的代码如下:
// 创建一个状态栏显示栏目。
const rateBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 1);
function showRate(editor: vscode.TextEditor) {
// 获取当前Tab页代码
const code = editor.document.getText();
// 计算代码注释率
const rate = analysisCode(code);
// 展示注释率
rateBar.text = rate;
rateBar.color = 'yellow';
rateBar.show();
}
3)、分析代码注释率
这一步与vscode无关。计算方法就仁者见仁,智者见智了。为了防止各种 edge case,笔者分析代码的抽象语法树,统计其中属于注释的语法节点,来计算注释率。代码如下:
function analysisCode(code: string) {
const ast = ts.createSourceFile(
"",
code,
ts.ScriptTarget.ES2015,
true,
ts.ScriptKind.TSX
);
let commentLine = 0;
let commentPoses = [];
function findCommentPos(node: ts.Node) {
if (!commentPoses.find(num => num === node.getFullStart())) {
commentPoses.push(node.getFullStart());
}
if (node) {
ts.forEachChild(node, findCommentPos);
}
}
ts.forEachChild(ast, findCommentPos);
commentPoses.forEach(pos => {
const comments = ts.getLeadingCommentRanges(code, pos);
comments && comments.forEach(comment => {
const commentCode = code.slice(comment.pos, comment.end);
console.log(commentCode);
commentLine += commentCode.split('\n').length;
});
})
return '代码注释率: ' + (commentLine / code.split('\n').length * 100 + '').slice(0, 4) + '%';
}
4) 发布
如果你是第一次进行 vscode 扩展发布,需要先申请发布账号。
发布账号申请成功后,用如下命令进行扩展发布:
npm install -g vsce vsce publish
本文中的这个示例,源码笔者已经上传到 Github。源码地址:
https://github.com/nefe/vscode-extension-tutorial
,并且已发布到 vscode 扩展市场。笔者可在扩展市场中搜索 hello-world:
vscode 插件开发案例
这里介绍一些笔者团队开发的一些扩展。
toolkits
提供 iron-redux 的 snippets,和 iron-redux 的动态 action 创建功能。
kiwi
kiwi 是笔者团队开发的一站式国际化解决方案。其主要功能如下:
-
中文抽取
-
中文回显
使用 I18N 后,代码丧失了一部分可读性,因此扩展还提供了中文回显功能。
-
中文查找
使用了 I18N 之后,代码中不再有中文,当业务中碰到问题需要定位对应代码位置非常困难。因此扩展提供了中文查找功能。
vscode-pont
下期介绍,敬请期待...
敲重点
新能源前端团队技术氛围好,团队大神多(妹纸也多),业务扩张,前途无量! 热烈欢迎联系笔者转岗~