笔者从业以来,各路插件开发无算,而 vscode 把插件开发体验做到了极致。其开发体验,如沐春风,如丝般顺滑,经常写完了还想删掉再写一遍!
vscode 扩展的内置脚手架细心且精致,一键生成后即可运行。vscode 库类型完美,因此开发者可以仅通过 IDE 提示来猜到 API,省去了很多文档查阅成本。最后,vscode 扩展开发文档丰富、开发体系清晰。
废话少说,让我们进入正题吧。
认识 vscode
vscode 由 electron 开发,通过 webview 渲染,编辑器基于 monaco editor 。可以通过切换开发人员工具来验证,如下图:
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
下期介绍,敬请期待...
敲重点
笔者团队技术氛围好,团队大神多(妹纸也多),业务扩张,前途无量! 快用简历来砸我!