前言
经过两个周的努力,昨天成功发布人生第一个插件 vscode-cats
,本文给大家介绍一下插件的开发过程,顺便也给自己做个记录。
插件下载: VSCode 扩展中直接搜索 vscode-cats 即可。
-
应用市场: vscode-cats
-
github: vscode-cats
如果能给 github
点个 star
就更完美了。
最开始开发 vscode-cats
时,感觉真的是暗无天日、遥遥无期。首先文档全是英文,看起来还是有几分吃力;二就是这种插件的模式实现 VSCode
并不提倡,因此 VSCode
官方并未提供类似的案例,但皇天不负有心人,多种方式去搜索、查询,终于查到了 background
插件(我感觉 background
插件的开发大佬很有可能是当前模式的先导者),后面又查到了 vscode-live2d
插件,通过钻研两位大佬的设计思路,终于最后成功做出 vscode-cats
插件。
环境准备
在开发 VSCode
插件之前,我们需要先安装两个依赖
- yeoman:
npm install -g yo
- generator-code:
npm install -g generator-code
初始化项目
进入要开发插件的目录,执行 yo code
指令,就会进入如下界面:
vscode-cats
插件使用的是 ts
开发,因此我们选择 New Extension (TypeScript)
,根据界面中要求操作,等到依赖安装完毕,插件 demo
项目初始化完毕。
初始化后的目录结构大致如下(只显示重要部分):
├── CHANGELOG.md // 版本更迭记录
├── README.md // 插件说明文档
├── src
│ └── extension.ts // 入口文件
├── package.json //
├── tsconfig.json // ts配置
├── test // 测试
核心文件介绍
学习 VSCode
插件开发,有两个特别重要的文件: package.json
extension.ts
,学会这两个文件后,就能进行简单的 VSCode
插件开发。
package.json
package.json
声明插件和命令的配置文件,用来注册命令等配置。
package.json
有很多字段属性可以配置,这里我就简介几个比较重要的配置。
activationEvents 属性
扩展的活动事件数组,在那些情况下事件会被激活。
demo
中配置的时 onCommand
指令,通过命令可以触发
"activationEvents": [
"onCommand:demo.helloWorld"
],
插件中使用的是 “*” ,所有类型的事件都可以触发激活
"activationEvents": [
"*"
],
关于 activationEvents
更详细的配置: https://code.visualstudio.com/api/references/activation-events
contributes 配置贡献点
常用的有 command
、configuration
等。
command
与活动事件列表里的 onCommand
指令相对应,在这里配置完毕后,就可以通过命令进行访问。
demo
中配置如下:
"commands": [
{
"command": "demo.helloWorld",
"title": "Hello World"
}
]
configuration
configuration
配置的属性会在 setting.json
中和 VSCode
插件设置页面通过 UI
格式显示。
撸猫插件给喵咪添加了下面的配置:
配置 | 描述 |
---|---|
vscode-cats.enabled | true:启用插件、false:禁用插件 |
vscode-cats.model | 更换喵咪 |
vscode-cats.modelWidth | 自定义喵咪宽度 |
vscode-cats.modelHeight | 自定义喵咪高度 |
vscode-cats.moveX | 自定义喵咪水平位置 |
vscode-cats.moveY | 自定义喵咪垂直位置 |
vscode-cats.opacity | 设置喵咪透明度 |
vscode-cats.position | 设置喵咪左右定位 |
下面以两个属性举一下例子:
"configuration": [
{
"title": "喵咪配置",
"type": "Object",
"properties": {
"vscode-cats.enabled": {
"type": "boolean",
"default": true,
"description": "是否启用喵咪"
},
"vscode-cats.model": {
"type": "string",
"enum": [
"tororo",
"hijiki"
],
"default": "tororo",
"description": "选那只喵咪"
}
},
}
]
配置完毕后,就可以在 setting.json
和 UI
中看到属性
extension.ts
extension
文件为项目的入口文件,该文件中提供两个重要方法: active deactive
。
active
: 插件激活时执行的函数deactive
: 插件被销毁时调用的函数
export function activate(context: vscode.ExtensionContext) {
// 这里的代码只会在插件激活时执行一次
console.log('Congratulations, your extension "demo" is now active!');
// 定义在 package.json 中的命令在这里定义
// 提供 registerCommand 来注册实现代码
// commandId 参数必须与 package.json 匹配
let disposable = vscode.commands.registerCommand('demo.helloWorld', () => {
// 当命令触发时,这里的代码执行
// 显示提示信息框
vscode.window.showInformationMessage('Hello World from demo!');
});
context.subscriptions.push(disposable);
}
// 插件停用时调用
export function deactivate() {}
vscode-cats 开发
上面简单介绍了 VSCode
插件开发中必须要了解的基本知识,有了这些知识做基础,接下来一起看一下 vscode-cats
的实现。
架构
首先来看一下 vscode-cats
插件的项目结构
- extension.ts: 项目入口
- FileType.ts: 文件类型(未修改过、hack过的旧版本、hack过的新版本)
- getHTML.ts: 获取能渲染喵咪的 workbench.html
- HTML.ts: 实现检查、替换、恢复 workbench.html
- originHTML: 删除插件,恢复 workbench.html 文件
- Home.ts: 项目的根文件
- uninstall.ts: 插件卸载
- utils: 工具函数
- version.ts: 插件版本
- vsHelp.ts: 封装 VSCode 自身的信息提示功能
实现思路
- 预备工作
- 通过
fs
模块获取到workbench.html
路径 - 编写读取文件内容
getContent
、更改文件内容saveContent
方法 - 封装信息提示框函数
showInfo
和提示信息并重启showInfoRestart
函数 - 通过
vscode.workspace.getConfiguration
获取到插件的配置项 - 将能实现喵咪的
HTML
代码添加到getHTML.ts
并且将配置项集成到HTML
中 - 将原来的
workbench.html
内HTML
代码保存到origin HTML.ts
中
- 通过
- 安装插件或激活插件:
- 编写
install
方法: 获取到config
信息,将config
信息传递给getHTML
,将生成的HTML
代码写入workbench.html
中 - 判断插件是否为第一次安装、旧版本,如果是,执行
install
方法
- 编写
- 卸载插件或关闭插件:
uninstall
: 从originHTML
获取到原来的HTML
代码,写入workbench.html
如何获取当前版本是否为新版本: 通过给 workbench.html 添加标识实现,例如当前插件添加的标识是
<!-- /*ext.${extName}.ver.${version}*/ -->
核心代码
- 获取
workbench.html
路径
const base = path.dirname(require.main.filename);
const filePath = path.join(
base,
"vs",
"code",
"electron-browser",
"workbench",
"workbench.html"
);
- 读写文件
export const saveContent = function (filePath, content: string): void {
fs.writeFileSync(filePath, content, "utf-8");
};
export const getContent = function (filePath): string {
return fs.readFileSync(filePath, "utf-8");
};
- 读取插件配置
let config = vscode.workspace.getConfiguration(this.configName);
- install
public install(refresh?: boolean): void {
let lastConfig = this.config; // 之前的配置
let config = vscode.workspace.getConfiguration(this.configName); // 当前用户配置
// 1.如果配置文件改变到时候,当前插件配置没有改变,则返回
if (!refresh && JSON.stringify(lastConfig) === JSON.stringify(config)) {
return;
}
// 之后操作有两种:1.初次加载 2.配置文件改变
// 2.两次配置均为,未启动插件
if (!lastConfig.enabled && !config.enabled) {
return;
}
// 3.保存当前配置
this.config = config; // 更新配置
// 4.如果关闭插件
if (!config.enabled) {
this.uninstall();
vsHelp.showInfoRestart(this.extName + "已关闭插件,请重新启动!");
return;
}
// 5.hack 样式
// 自定义的样式内容
let content = getNewHtml(config, this.extName, this.version).replace(
/\s*$/,
""
);
// 将插件的HTML写入 workbench.html 文件
saveContent(this.filePath, content);
vsHelp.showInfoRestart(this.extName + " 已更新配置,请重新启动!");
}
- uninstall
private uninstall(): boolean {
try {
let content = renewHTML();
saveContent(this.filePath, content);
return true;
} catch (ex) {
return false;
}
}
打包
打包的实现比较简单,安装 vsce
依赖包(npm install -g vsce
)。
之后通过 vsce package
就可以将插件打包成 vsix
文件。
最后就可以把 vsix
安装到 VSCode
中试一下是否可用。
发布
关于发布我就不多啰啰了,具体可以参考官方文档。
但一定注意在
maketPlace
注册开发者时,需要翻墙,那个注册页面访问了谷歌。(血泪教训)
后语
伙伴们,如果大家感觉本文对你有一些帮助,给阿包点一个赞👍或者关注➕都是对我最大的支持。
另外如果本文章有问题,或者对文章其中一部分不理解,都可以评论区回复我,我们来一起讨论,共同学习,一起进步!