VS Code 插件开发入门教程

发表于 3年以前  | 总阅读数:394 次

之前一直以为开发VS code插件是一件很难的事情,后来工作上需要搞一个效率小工具,就试着找了些资料来入门,发现其实就入门和开发一些简单功能的插件来说难度还是很低的。因为vscode本身是基于electron开发的,所以总体来说开发插件就是在写node代码,额外再加一些编辑器api,插件发布的过程和npm包的发布很类似。

vscode官方提供的脚手架还帮忙加上了调试配置,调试非常方便。下面就来说下具体步骤,在学习的过程中参考了一些博客,放在了最后面。

环境准备

这个很简单,我就直接拷贝过来了。

  • nodejs: 建议使用 LTS 版本
  • npm: 建议最新版本
  • yeoman : npm install -g yo
  • generator-code : npm install -g generator-code

另外小TIPS,我们平时直接安装的插件所在目录是~/.vscode/extensions,有兴趣的可以看看这些插件是怎么实现的。

脚手架

安装的yo可以直接生成一个Hello World版本的插件目录。执行

yo code

即会提示一些问题,按照个人喜好填写即可,最后会生成样板代码:

.
├── CHANGELOG.md                 插件变更记录
├── README.md
├── extension.js                 插件入口main文件
├── jsconfig.json                编辑器关于js的配置
├── package.json                 全局配置
├── test                         测试代码文件夹
│   ├── extension.test.js
│   └── index.js
├── vsc-extension-quickstart.md  新手介绍
└── yarn.lock

其中的quickstart.md是新手引导,里面包含了对文件的作用解析、如何运行插件、测试插等等,推荐去看一看,我们在下面也会介绍一些。除此之外在package.json里也包含了很多非常重要的信息:

{
  "name": "hello-world", // 插件名
  "displayName": "hello-world",
  "description": "hello world", // 插件描述
  "version": "0.0.1",
  "engines": {
    "vscode": "^1.35.0" // 运行插件需要vscode最低版本
  },
  "categories": ["Other"],
  "activationEvents": ["onCommand:extension.helloWorld"], // 如何激活插件:在命令面板(Command+Shift+P吊起)输入helloWorld. 注意command名需要在contributes.commands中有配置
  "main": "./extension.js", // 插件入口
  "contributes": {
    "commands": [
      // 此数组表示插件支持的所有命令
      {
        "command": "extension.helloWorld", // 命令对应的Command,需要和代码里保持一致
        "title": "Hello World" // 命令的显示名称
      }
    ]
  },
  "scripts": {
    // 正常的npm script
    "postinstall": "node ./node_modules/vscode/bin/install",
    "test": "node ./node_modules/vscode/bin/test"
  },
  "devDependencies": {
    // 依赖包
    "typescript": "^3.3.1",
    "vscode": "^1.1.28",
    "eslint": "^5.13.0",
    "@types/node": "^10.12.21",
    "@types/mocha": "^2.2.42"
  }
}

启动、调试插件

启动运行

脚手架生成的其实就是一个node应用,直接按F5即可运行。对配置感兴趣的也可以查看根目录下的.vscode/launch.json

跑起来以后默认会新开一个vscode窗口,然后会发现什么都没有发生,这是由插件的启动方式决定的,配置于package.json里的activationEvents项。常用的有:

  • onLanguage 在打开特定语言类型的文件后激活
  • onCommand 在执行特定命令后激活

由于我们的插件是配置的onCommand启动,并且指定的命令名是Hello World,所以我们在新开的vscode窗口中按下快捷键Command+Shift+P后再找到Hello World,选中并执行即可。

最后顺利的话,编辑器右下角会弹出Hello World!。

如果细心的话,还会在源窗口的控制台的调试控制台tab 中看到如下输出:

Congratulations, your extension "hello-world" is now active!

这个就是由插件的真正代码部分输出的了。我们接下来看看extension.js的内容:

// vscode编辑器api入口
const vscode = require('vscode');

/**
 * 此生命周期方法在插件激活时执行
 * @param {vscode.ExtensionContext} context
 */
function activate(context) {
  // console的各种方法都是输出在`调试控制台`tab下
  console.log('Congratulations, your extension "hello-world" is now active!');

  // registerCommand用于注册命令并提供具体逻辑,命令名需要和package.json里写的一致。
  // 回调函数在命令被触发时执行。
  let disposable = vscode.commands.registerCommand('extension.helloWorld', function() {
    // 在编辑器右下角展示一个message box
    vscode.window.showInformationMessage('Hello World!');
  });

  // 将registerCommand的返回值放入subscriptions可以自动执行内存回收逻辑。
  context.subscriptions.push(disposable);
}
exports.activate = activate;

// 当插件被设置为无效时执行此生命周期钩子
function deactivate() {}

module.exports = {
  activate,
  deactivate,
};

以上就是此插件的完整逻辑了,配置注释是很简单的。可以看到主要就是两个生命周期函数,另外搭配一些编辑器api就完成了。

调试

脚手架已经贴心的帮我们加了调试配置,我们只用添加断点即可:

Command 配置

上面提到了生成一个command只需要 2 步,先是利用vscode.commands.registerCommand注册一个,然后再到package.json里的contributes.commands中配置即可。围绕command还可以做一些其他事情,最常见的就是配置右键菜单和快捷键。

右键菜单

表示右键的菜单里出现指定command,配置方法:

"contributes":{
  "menus": {
    "editor/context": [
      {
        "when": "editorHasSelection && resourceFilename =~ /.js|.vue|.ts/", // 出现时机,当编辑器中有选中文本同时文件名后缀是js/vue/ts
        "command": "extension.starling_textSearch", // 需要在`contributes.commands`存在此命令
        "group": "6_Starling" // 命令所在的组,右键菜单可以分组,组与组之间存在分隔线
      },
    ]
  }
}

快捷键

有了快捷键后,就不用每次在命令面板里查找并运行命令了,同样是在package.json中配置:

"contributes": {
  "keybindings": [
    {
      "command": "extension.starling_textSearch",
      "key": "ctrl+f11", // 在Windows上的快捷键
      "mac": "cmd+f11", // 在mac上的快捷键
      "when": "editorTextFocus" // 出现时机, 当编辑器焦点在某个文本中
    }
  ],
}

发布

主要参考的是官方文档

首先需要安装vsce工具:

npm install -g vsce

本地打包将插件打包成.vsix文件。

vsce package

会在项目根目录生成hello-world-0.0.1.vsix,然后在编辑器的插件面板选择从VSIX安装即可:

发布到插件市场

  • 需要获取一个token,参考官方文档
  • 利用token创建一个publisher,这是在插件市场的用户
vsce create-publisher (publisher name)
  • 本地登录此用户
vsce login (publisher name)
  • 发布插件
vsce publish

顺利的话在控制台会提示发布成功,然后过几分钟就可以在插件市场搜到自己的插件啦!

版本升级

当插件内容发生变更时,重新发布时最好更新版本号,vsce可以遵循语义化版本指定升级大(major)/小(minor)/补丁(patch)版本,也可以直接指定版本号。例如只升级小版本:

vsce publish minor

如果插件代码在gitlab上,因为仓库在内网,需要事先将README里的图片替换为公网cdn上的路径。

snippets

snippets是代码片段,可以理解为代码快捷键,在输入很少量触发代码后即可联想出一大坨关联代码,非常方便。对于js、ts、vue都可以在插件市场找到非常多的snippets插件。

开发snippets只用两步:

  • 编写snippets映射文件,它是一个json,例如javascript.json:
{
  "this$t": {
    "prefix": "tt'", // 触发代码
    "body": [
      // 联想出来的关联代码
      "this.\\$t('${1:key}')" // ${1: key} 是占位符,联想出来后会自动聚焦在这里
    ],
    "description": "this.$t" // snippets描述,当有多个匹配的代码片段时,可以用来识别
  }
}
  • 在package.json中配置
"contributes": {
  "snippets": [
    {
      "language": "javascript", // 代码片段起作用的语言类型
      "path": "./src/snippets/javascript.json" // 对应的映射文件
    }
  ]
}

最后就可以在编辑器看到效果了:

  • 更多细节参考snippets-syntax

插件默认配置

很多插件是需要一些额外配置才能工作的,设置默认配置同样在package.json里:

"contributes": {
  "configuration": { // 默认配置
    "type": "object",
    "title": "",
    "required": [
      "sid"
    ],
    "properties": {
      "includes": {
        "type": "Array",
        "default": [
          "json"
        ],
        "description": "文件类型过滤器"
      }
    }
  },
}

默认配置是json schema格式,在覆盖默认配置时如果校验出错会有提示。

插件中使用getConfiguration来读取配置:

function getConfig() {
  const config = vscode.workspace.getConfiguration();
  const includes: string[] | undefined = config.get('includes'); // 获取指定配置项

  return {
    includes: includes || [],
  };
}

监听配置项修改

在用户安装了插件后,可能会修改配置,如何实时监听配置项的修改呢?vscode提供了onDidChangeConfiguration事件监听。

vscode.workspace.onDidChangeConfiguration(function(event) {
  const configList = ['includes'];
  // affectsConfiguration: 判断是否变更了指定配置项
  const affected = configList.some(item => event.affectsConfiguration(item));
  if (affected) {
    // do some thing ...
  }
});

常见编辑器 api

所有vscode相关api都可以在官网文档查找,vscode内部也集成了.d.ts文件,编辑器内直接跳转定义即可。这里只列举一些常见的api.

  • messgae

用于展示提示性消息,出现在编辑器右下角,而不是顶部或右上角。

和console类似,提供了普通消息、警告消息、错误消息。

vscode.window.showInformationMessage('普通消息');
vscode.window.showWarningMessage('警告消息');
vscode.window.showErrorMessage('错误消息');

消息也支持交互按钮,当选中按钮时返回的是按钮本身:

vscode.window.showErrorMessage(`与starling的远程交互依赖vscode-starling.sid配置项`, '打开配置项').then(selection => {
  if (selection === '打开配置项') {
    vscode.commands.executeCommand('workbench.action.openSettings');
  }
});

input box

在编辑器顶部展示一个input输入框,使用vscode.window.showInputBox,会返回一个Promise:

const text: string | undefined = await vscode.window.showInputBox({
  '最后一步,输入文案'
})

quick pick

用于从一组选项中选择一个,类似于select组件。使用vscode.window.showQuickPick,同样返回一个Promise,resolve时得到被选中的选项或undefined:

const lang: string | undefined = await vscode.window.showQuickPick(['en', 'zh', 'ja'], {
  placeHolder: '第一步:选择语言',
});

每个选项也可以是对象类型:

const option: Object | undefined = await vscode.window.showQuickPick([{ id: 1, name: 'a' }, { id: 2, name: 'b' }, { id: 3, name: 'c' }], {
  placeHolder: 'select an option',
});

output channel

在利用Control + ~打开控制台后,会出现 4 个tab,从左到右依次是问题、输出、调试控制台、终端。output channel就是用于控制输出 tab的内容,可以往其中追加文本、追加行、清空,可以将其看成一个简单的文件。output channel适用于一次展示大量信息.

使用vscode.window.createOutputChannel创建output channel实例,然后就可以操作各种api了。

const opc = vscode.window.createOutputChannel('textSearch'); // 可以有多个OutputChannel共存,使用参数名区分

opc.clear(); // 清空
opc.appendLine('水电费'); // 追加一行
opc.show(); // 打开控制台并切换到OutputChannel tab

一个例子:

file selector

有些时候需要操作本地文件系统,例如选择某个文件、将文件保存到指定位置等。

  • 保存文件到指定位置使用showSaveDialog,它会打开文件选择器弹窗,选择了保存路径后点击确定会返回选中的路径,如果点击取消会返回undefined。
// 让用户手动选择文件的的存储路径
const uri = await vscode.window.showSaveDialog({
  filters: {
    zip: ['zip'], // 文件类型过滤
  },
});
if (!uri) {
  return false;
}

writeFile(uri.fsPath); // 写入文件
  • 文件选择showOpenDialog同样会打开文件选择器弹窗,不过这次是用于选择文件,如果有选择文件会返回选中的文件路径,反之返回undefined。
// showOpenDialog返回的是文件路径数组
const uris = await window.showOpenDialog({
  canSelectFolders: false, // 是否可以选择文件夹
  canSelectMany: false, // 是否可以选择多个文件
  filters: {
    json: ['json'], // 文件类型过滤
  },
});

if (!uris || !uris.length) {
  return;
}

handleFiles(uris);

hover

有时候需要在hover到文本上时展示一些提示信息,例如eslint插件在hover到不合规的代码上时会展示具体违反了哪些规则:

处理hover需要注册一个hover处理器,vscode会在hover到文本上时自动调用处理器,同时传递hover相关的信息。例如一个展示光标所在的单词hover处理器:

/**
 * document: 打开的文本
 * position:hover的位置
 * token: 用于取消hover处理器作用
 */
async function hover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken) {
  const line = document.lineAt(position).text; // 光标所在的行
  // getWordRangeAtPosition获取光标所在单词的行列号范围;getText获取指定范围的文本
  const positionWord = document.getText(document.getWordRangeAtPosition(position));

  console.log('光标所在位置的单词是:', positionWord);
}

// registerHoverProvider的第一个参数数组表明此处理器的作用范围
const hoverDisposable = vscode.languages.registerHoverProvider(['javascript', 'vue'], {
  provideHover: hover,
});

context.subscriptions.push(hoverDisposable);

selection

与hover类似,有时候需要处理选中的文本,获取它是通过vscode.TextEditor实例上的属性,有两个相关属性

  • selections:所有被选中的文本信息
  • selection:第一个被选中的文本信息, 等同于selections[0]

获取TextEditor的一个方法是通过注册textEditorCommand,会在回调函数里提供TextEditor实例,例如展示选中文本:

let command = vscode.commands.registerTextEditorCommand('extension.selection', function(textEditor, edit) {
  const text = textEditor.document.getText(textEditor.selection);
  console.log('选中的文本是:', text);
});

context.subscriptions.push(command);

FileSystemWatcher

用于监听文件是否发生了变化,可以监听到新建、更新、删除这 3 种事件,也可以选择忽略其中某个类型事件。创建watcher是利用vscode.workspace.createFileSystemWatcher:

function createFileSystemWatcher(globPattern: GlobPattern, ignoreCreateEvents?: boolean, ignoreChangeEvents?: boolean, ignoreDeleteEvents?: boolean): FileSystemWatcher;

例如监听所有js文件的变动:

const watcher = vscode.workspace.createFileSystemWatcher('*.js', false, false, false);
watcher.onDidChange(e => { // 文件发生更新
  console.log('js changed,' e.fsPath);
});
watcher.onDidCreate(e => { // 新建了js文件
  console.log('js created,' e.fsPath);
});
watcher.onDidDelete(e => { // 删除了js文件
  console.log('js deleted,' e.fsPath);
});

参考文章

  • https://code.visualstudio.com/api
  • VSCode插件开发全攻略:https://www.cnblogs.com/liuxianan/p/vscode-plugin-overview.html
  • VSCode插件开发急速入门:https://juejin.im/entry/6844903640826642440

本文由哈喽比特于3年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/TTQXhtqcfWqQuzHwL7cYww

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:1年以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:1年以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:1年以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:1年以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:1年以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:1年以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:1年以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:1年以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:1年以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:1年以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:1年以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:1年以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:1年以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:1年以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:1年以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:1年以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:1年以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:1年以前  |  398次阅读  |  详细内容 »
 相关文章
Android插件化方案 5年以前  |  237231次阅读
vscode超好用的代码书签插件Bookmarks 2年以前  |  8065次阅读
 目录