VSCode插件 - Json 转 Enums 代码自动生成

VSCode 目前应该是前端的主流开发IDE,掌握一些 VSCode 插件的开发方法,为自己的项目量身定做一些插件,可以大大提高日常开发效率。

需求背景

我们项目需要很多常量的枚举值,这些值保存在后端,比如一个订单有多种状态:Pending:1,Done:2,页面需要依赖这些状态值来进行逻辑判断。我们的项目使用了 Typescript ,为了让代码能够有提示功能,也为了让代码更加语义化,我们需要维护一个全局的 Typescript 的枚举(Enums)值,这个值会增量更新,所以我们为了省掉这部分人工工作,开发一款 VSCode 插件,来完成增量更新的工作。我们先来看一下效果

vscode2.gif

VSCode 插件简介

VSCode 是微软出的一款轻量级代码编辑器,免费而且功能强大,对 JavaScript 和 NodeJS 的支持非常好,VSCode 本身都是用浏览器实现的,所以其插件不用说肯定也是基于HTML+JS等前端技术实现,从形式上看就是一个类似于 npm 包的 vsix 文件,只不过按照一些特殊规范来实现一些特殊功能。

具体实现方案

接下来没有过多的 API 的使用方法,本文直接介绍具体的实现方法和使用到的 API ,具体的 API 文档可以自己有兴趣去看一下教程。

1 执行入口

一般插件默认的执行入口文件都是 extension.js 文件,文件中写入以下代码

module.exports = context => {
  context.subscriptions.push(
    registerCommand(operation.generateEnums.cmd, uri => {
      updateEnums({ context })
    })
  )
}

也就是我们先注册一个叫做 generateEnums 的命令,等触发了以后就执行 updateEnums 这个方法。

2 右键触发命令

我们想要实现点击鼠标右键就能出发命令的功能,需要在 package.json 的文件中做如下配置

"contributes": {
  "commands": [
    {
      "command": "extension.generateEnums",
      "title": "Generate Enums"
    }
  ],
}

3 updateEnums 函数的实现

此函数是工具逻辑的核心

module.exports = async ({ editor }) => {

  // 保留原有的TS代码
  let preTsCode = ''
 
  // 获取鼠标右键的文件的代码
  let currentEditor = getEditor(editor)
  ...
  // 遍历每一行代码,通过正则表达式将枚举值的 key 值从代码中找出,将页面代码转换为一个对象用来在下一步与接口返回的数据进行对比
  for (let i = 0; i < lineCount; i++) {
    const enumsKeyRegExp = new RegExp(/(?<=enum).*?(?={)/)
    const enumsValueRegExp = new RegExp(/.*?(?=,)/)
    const matchResult = lineText.match(enumsKeyRegExp)
    keyValue[tempEnumsKey][key] = value && value[0].trim()
  }
  // 获取远端的数据并对比本地与远端
  try {
    // 此处通过插件配置获取数据
    const request = axios.create({
      headers: { ...vscode.workspace.getConfiguration().get('extension.headers') }
    })
    const enumApi = vscode.workspace.getConfiguration().get('extension.enumApiUrl')
    Object.keys(res).forEach(item => {
      // 后端返回数据与当前文件代码数据进行比对
      ...
      }
    })
    // 将页面当前的代码加上比对出来的增加的代码合并
    const result = preTsCode + tsCode
    fs.writeFile(currentEditor.document.uri.fsPath, result, err => {
      // 将转换后的代码写入文件中
      ...
    })
  }
}

整体的逻辑为:

  1. 获取鼠标点击右键操作的文件的代码
  2. 代码通过正则表达式,枚举值转换为 Key-Value 形式,用来后来和接口返回数据进行比对
  3. 通过插件配置的 API 地址,获取后端返回的数据
  4. 将后端返回的数据与步骤2中生成的数据进行对比,如果数据中没有,那就进行增量更新。(此步骤只对比 Key 值是否存在,对于Value不进行比对)
  5. 将对比更新后的数据,转换为 TS 代码,写回文件中

3.1 插件安装方法

插件已经发布到 VSCode 商店

截屏2021-07-07 下午2.35.21.png

3.2 配置信息的设置

如果想要让你的插件可接收配置信息,在 package.json 文件中加入

  "configuration": {
    "type": "object",
    "title": "WMS-ENUMS-GENERATION",
    "properties": {
      "extension.enumApiUrl": {
      "type": "string",
      "default": "",
      "description": "Please input your project's enums api(example:  http://xxx.com/api/apps/xxx/enums)"
      },
      "extension.headers": {
         "type": "object",
         "default": "",
         "description": "{csrftoken: xxx, token: xxx}"
      }
    }
  }

然后在插件配置页面就可以看到信息录入的地方了

截屏2021-07-07 下午2.39.58.png

截屏2021-07-07 下午2.40.08.png

3.3 可接收的后端返回的数据结构

response: {
  data: {
    ABCClassification: {
      A: 1,
      B: 2,
      C: 3,
      EXCLUDED: 5,
      SA: 4,
      UNDEFINED: 0
    },
    AdjustTaskStatus: [
      {key: "Created", value: 1},
     {key: "Pending", value: 2},
     {key: "Locked", value: 21}
    ]
  },
  message: "success",
  retcode: 0
}

结合我们自身的业务特点,目前插件支持返回 Key-Value 这种形式,或者返回一个数据,但数据里面是 key 与 value 分别表示的一个对象。

4 总结

开发自定义的 VSCode 插件可以帮助我们提高工作效率,此工具在一些方面的确存在一些通用性方面的问题,但工具最开始的初衷也只是一个项目内部自定的工具。在数据接收方面,如果有更好的交互方式也希望大家能在下面评论区指导。希望本文能带给你一些想法,也能通过本文了解到开发一个插件的一些步骤与思路。

引用

VSCode插件全攻略