[手把手系列] 开发一个 VS Code 业务插件

CodeNebula
• 阅读 7354

[手把手系列]  开发一个 VS Code  业务插件

背景

VS Code应该都很熟悉,平时吃饭的工具, 每天都要用。

它是微软出的一款轻量级代码编辑器,免费而且功能强大,以功能强大、提示友好、不错的性能和颜值俘获了大量开发者的青睐。

对JavaScript和NodeJS的支持非常好,自带很多功能,如代码格式化,代码智能提示补全等。

对于VS Code 插件开发, 大家可能不太熟悉, 但是我觉得大家都应该 学习, 掌握一下这个技能

因为每个人都会多多少少有一些自己的特殊定制需求,遇到类似提升开发效率的时候,大部分想到的都是写一些脚本工具浏览器插件等。

掌握IDE插件开发之后, 就会发现: 有些问题可以通过更高效的方式来解决,毕竟IDE才是我们程序员每天接触最多的东西

我最近也开发了一款VS Code 插件, 作为自己项目的辅助工具, 中间也踩了一些坑, 借助这个机会分享给大家, 希望对大家有所启发。

附项目源码地址: https://github.com/beMySun/wm...

需求场景

我所做的是一个国际化项目, 需要支持多语言, 翻译的相关资源托管在我们的翻译平台上, 开发的时候, 录入翻译字段的 key 和 value, 如下图:

录入key:
[手把手系列]  开发一个 VS Code  业务插件

录入value:

[手把手系列]  开发一个 VS Code  业务插件

录入完成之后, 为了方便本地开发, 需要下载翻译好的资源:

[手把手系列]  开发一个 VS Code  业务插件

下载到本地的就是一些json文件:

[手把手系列]  开发一个 VS Code  业务插件

然后需要导入到项目中:

[手把手系列]  开发一个 VS Code  业务插件

这一套流程十分的麻烦, 费时费力, 为了提升这部分的操作效率, 我开发了一个脚本命令,可以自动下载资源, 并输入到对应的目录中:

[手把手系列]  开发一个 VS Code  业务插件

十分的方便。

下面,我就介绍下具体的开发流程和开发细节。

工程搭建

VS Code 插件开发, 选用官方推荐的工具: Yo Code

npm install -g yo generator-code

然后执行:

yo code

vscode插件可以使用TypeScript来编写(官方推荐),也可以使用JavaScript,本文统一使用后者,不过使用哪种方式,能实现的功能都是一样的。

借用一张图:

[手把手系列]  开发一个 VS Code  业务插件

根据指引, 一步步生成即可, 这样, 就得到了一个干净的插件工程了。

[手把手系列]  开发一个 VS Code  业务插件

其中的 src, utils images目录是我后面添加的, 可以忽略。

⚠️ 如果生成的过程中, 报了版本错误, 可以修改这里:

[手把手系列]  开发一个 VS Code  业务插件

然后, 就开始正式的插件开发了。

插件开发

这里, 我们需要主要关注两个文件:

  1. package.json
  2. extension.js

package.json中,我们定义的是需要 执行的命令 和添加 VS Code 菜单

[手把手系列]  开发一个 VS Code  业务插件

extension.js 中添加我们自定义的功能:

[手把手系列]  开发一个 VS Code  业务插件

downloadI18nResources文件中的内容:

const vscode = require('vscode');
const fileloader = require('./download');

module.exports = function (context) {
  context.subscriptions.push(
    vscode.commands.registerCommand('i18n.downloadI18nResources', () => {
      const showInformationMessage = vscode.window.showInformationMessage;
      fileloader.download(showInformationMessage);
    })
  );
};

download 里面的逻辑就不细说了, 感兴趣的可以看源码。

有一点需要提一下:

就是脚本执行之后, 文件输出路径的问题:

const directoryPath = path.resolve(__dirname, 'src/i18n/locales');

一开始我是这么写的, 在插件测试的时候没有问题, 可以输出, 但是输出的位置不对, 输出到了插件的工程目录里, 而我是需要输出到业务项目的工程目录里,原因就是在插件里没做区分。

在Node Js 中,文件路径大概有 __dirname, __filename, process.cwd(), ./ 或者 ../,前三个都是绝对路径,为了便于比较,./../ 我们通过 path.resolve('./')来转换为绝对路径。

简单说一下这几个路径的意思:

__dirname:    获得当前执行文件所在目录的完整目录名
__filename:   获得当前执行文件的带有完整绝对路径的文件名
process.cwd():获得当前执行node命令时候的文件夹目录名 
./:           文件所在目录

所以, 要解决上面描述的问题, 就要取得项目当前的路径:

const getCurrentOpenedFolderPath = () => {
  let path;
  if (vscode.window.activeTextEditor) {
    let workspaceFolder = vscode.workspace.getWorkspaceFolder(vscode.window.activeTextEditor.document.uri);
    path = workspaceFolder.uri.path;
  }
  return path;
};

const projectPath = getCurrentOpenedFolderPath();
const projectName = projectPath.split('/').pop();

// ...

// 把
const directoryPath = path.resolve(__dirname, 'src/i18n/locales');

// 纠正为:
const directoryPath = path.resolve(currnetPath, 'src/i18n/locales');

就可以了。

这里还需要生成多承文件夹, 写了一段同步脚本:

const path = require('path');
const fs = require('fs');

function mkdirsSync(dirname) {
  if (fs.existsSync(dirname)) {
    return true;
  } else {
    if (mkdirsSync(path.dirname(dirname))) {
      fs.mkdirSync(dirname);
      return true;
    }
  }
}

module.exports = {
  mkdirsSync
};

这样, 调用download方法, 就可以把下载的资源输出到正确的位置上了, 基础功能开发完成。

调试

工程创建完成之后, 你可以用自带的hello world! 来测试。

进入 debug 模式:点击 Fn + F5, 然后会跳出一个调试面板:

[手把手系列]  开发一个 VS Code  业务插件

在新出现的面板里, 点击shift + cmd + p 输入你的命令:

[手把手系列]  开发一个 VS Code  业务插件

为了方便,你也可以把命令定义到鼠标右键的menu 里, 这样就不用手动敲了:

[手把手系列]  开发一个 VS Code  业务插件

调试过程中,最好把开发工具, 和调试工具放在不同的屏幕里, 这样方便点, 更新代码之后, 点击那个绿色的图标按钮即可, 红色的图标是停止调试。

打包

开发完成之后, 可以先在本地安装调试:

vsce package

[手把手系列]  开发一个 VS Code  业务插件

得到一个vsxl文件, 然后安装到你的 VS Code 中:

在编辑器中, 输入 cmd + shift + p, 输入install:
[手把手系列]  开发一个 VS Code  业务插件

选择生成的安装包:

[手把手系列]  开发一个 VS Code  业务插件

安装成功:

[手把手系列]  开发一个 VS Code  业务插件

后续的流程也是一样的, 更新代码之后,都需要重新打包, 安装。

发布

最终开发完成之后, 可以发布到官方商店, 这样同事也能下载使用了。

还是要借助 vsce, 我们上面已经安装过了。

注册账号

首先访问 https://login.live.com/ 登录你的Microsoft账号,没有的先注册一个:

[手把手系列]  开发一个 VS Code  业务插件

然后访问: https://aka.ms/SignupAzureDevOps ,如果你从来没有使用过Azure,那么会看到如下提示:

[手把手系列]  开发一个 VS Code  业务插件

点击继续。

创建令牌

[手把手系列]  开发一个 VS Code  业务插件

[手把手系列]  开发一个 VS Code  业务插件

然后就创建成功了:

[手把手系列]  开发一个 VS Code  业务插件

生成的 token 记得复制一下, 下面要用。

[手把手系列]  开发一个 VS Code  业务插件

创建发布账号

获得个人访问令牌后,使用vsce以下命令创建新的发布者:

vsce create-publisher your-publisher-name

[手把手系列]  开发一个 VS Code  业务插件

需要注意的是, 这里的 your-publisher-name 需要和你的package.jsonauthor 中的字段保持一致, 否则就会报错, 修改之后就可以了:

[手把手系列]  开发一个 VS Code  业务插件

发布成功!

[手把手系列]  开发一个 VS Code  业务插件

过几分钟,应用商店中也能下载了:

[手把手系列]  开发一个 VS Code  业务插件

至此,一个基础的 VS Code 插件就彻底完成了。

最后

这个插件用了半天时间,只包含了基础功能, 后续还会做增强, 待完善的功能点:

  • 实现对比功能,把下载到本地的json文件,与系统中真正调用的对比, 找到那些在翻译平台中无用的翻译。
  • 实现自动生成翻译的json, 这样就不用手动去翻译平台添加, 可以在翻译平台上传文件, 或者自动上传。

对比功能本地已经开发完成了, 给你们看一下效果:

[手把手系列]  开发一个 VS Code  业务插件

竟然有那么多没有用到的翻译,还是非常震惊的, 不过结果应该有偏差, 需要逐个核对。

结尾

本文包含的代码, 已经在开头给出了, 如果有帮助到你的话,可以给个星星~

内容就是这么多, 希望对你有所启发。

文中若有笔误, 还请指正, 谢谢。

关注我

如果你觉得这篇内容对你挺有启发,那就关注我吧~

[手把手系列]  开发一个 VS Code  业务插件

更多精彩:

聊聊 ESM、Bundleless 、Vite 、Snowpack

记一次 「 无限列表 」滚动优化

「 面试三板斧 」之 代码分割(上)

「 面试三板斧 」之缓存 (上)

「 面试三板斧 」之缓存 (下)

「 面试三板斧 」之 HTTP (上)

「 面试三板斧 」之 HTTP (下)

「 面试三板斧 」之  this

参考资料

http://blog.haoji.me/vscode-p...

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
3年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Stella981 Stella981
3年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Easter79 Easter79
3年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Wesley13 Wesley13
3年前
Java日期时间API系列36
  十二时辰,古代劳动人民把一昼夜划分成十二个时段,每一个时段叫一个时辰。二十四小时和十二时辰对照表:时辰时间24时制子时深夜11:00凌晨01:0023:0001:00丑时上午01:00上午03:0001:0003:00寅时上午03:00上午0
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
美凌格栋栋酱 美凌格栋栋酱
5个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(