坏蛋Dan
知乎@坏蛋Dan
发布时间:2024.1.3

前言

之前写过几次vscode插件,但是过段时间自己就忘了流程了。。。。所以写个文章方便自己review

这次咱来写一个将$.ajax转换成axios的插件。

感兴趣的可以去看下,名字叫AJAX_JQ_2_AXIOS

github地址:


文档

官方有提供文档,虽然文档不是很详细

Your First Extension | Visual Studio Code Extension API


环境支持

这个yo[1](Yeoman)是一个多功能的npm包,可以看作是一个脚手架,里面不止有vscode插件的模板,还有其它比如eslint插件的模板等。

generator-code[2]则是yovscode extension相关的模板

其实也不一定非得安装,你也可以手搓一个。。(我第一次写的时候就是参考别人的项目手搓的。。。)

安装完之后可以开个终端看下


创建项目

在终端输入

然后就会有一连串的选项,选项都是大家知道的,比如是否使用ts或者webpack打包等,这里就不多说了。

创建完之后可以看到文件目录

其中test是写单元测试的地方。

extension.ts就是我们的入口,这篇文章是入门,所以不会有其它配置,这里就不多介绍其它文件了。

打开extension.ts文件你可以看到一个简单的结构

  • activate:这个函数会在某个时候激活,比如你运行某个指令的时候,这完全取决于你的配置。
  • deactivate:这个自然就是取消激活的时候触发的。

我们去到package.json文件中稍微看下

这个activationEvents[3]有很多场景,比如onStartupFinished等,你可以自由组合

而这个contributes[4]则是用来修改vscode自身的,比如你这个插件想改变配色,这个时候就可以用contributes.colors[5]

可以看到初始的激活场景就是当你F1选择该指令的时候,而我们的指令出现的地方目前仅能通过F1唤起指令面板才可以找到入口。

registerCommand[6]则是注册指令,可以传入一个回调。当这个指令被触发的时候就会执行这个回调,我们的主要代码就写在这里面。

运行

在运行之前,确保你的项目是在根目录,即非workspace,整个vscode界面只有你这个项目。因为可能会导致识别路径错误。

确保完之后直接F5,是的,直接F5,如果有弹出什么ts:watch出错啥的,直接忽略选择debug anyway

这个时候就会弹出一个新窗口,原来的窗口则显示这样

但是这不是我们的插件激活场景,我们的插件激活场景是在触发指令的时候。

我们按F1(在新弹出来的那个窗口),选择我们注册的指令,注意这里是和contributes.commands中你配置的指令的title关联的

然后按下确认

这个时候就出发我们registerCommand注册的回调了。

然后回到我们编写代码的窗口,你会发现终端输出了一段log

这就表示我们的插件被激活了。

那么到这,我们已经学会基础的使用了。

现在关闭之前弹出来的窗口,这样你这个插件就停止运行了。


引入依赖

我们这个是要做一个将$.ajax转换成axios + try catch代码的插件,那么这里就得用上babel[7]里的几个依赖了。

如果你对babel不是很了解,你可以看我之前写的一篇学习文章:babel入门学习 - 知乎 (zhihu.com)

然后我们来引入依赖,由于是ts项目,我们还得引入对应的types,避免报错。


项目配置

在开始敲代码之前,我们还需要配置一下我们的项目

ts配置

前面说了引入babel是不能直接在ts项目中用的,我们还得引入对应的types包,但是引入types包也还是不能直接用的,我们还得在tsconfig.json中配置下

其中我们最重要的是配置types

至于targetlib都是我用的api有需求才做的调整,我后面会用到String.prototype.replaceAll[8]这个方法,而这个方法的兼容性还是比较差的。


vscode指令配置

前面我们知道了contributes是用来修改vscode的,所以我们可以拓展一些场景用来作为我们的插件入口。

  • commands[9]:前面说过就是F1弹出来的指令查询框里的入口
  • menus[10]: 这个则是目录相关的,我这里选择的是编辑区域的右键弹出来的目录

  • group: 1_modification:这个则表示在目录的哪块区域

  • keybindings[11]:这个很好理解,就是快捷键,这里是区分MacOSLinuxWindow的,大家都知道是为啥,这里就不多说了。

那么就配置完了,接下来我们来开始写代码


实现

分析

既然我们是要将$.ajax转换成axios + try catch的方式,那么我们就需要了解这两个的格式和结构。

来看一个典型的$.ajax

传入一个对象,但这个对象它有属性,有method,而method中又还有function/arrow function的区别,我们要做的就是将以下的代码提取出来。

  • type
  • url
  • data
  • success
  • fail
  • error
  • complete

至于如何拿到这些,我们就需要借助babel了。

拿到之后我们直接就用str拼接即可,就不用babel/template[12]了。

获取选中区域

不过第一步得先拿到选中区域。怎么拿到选中区域呢?

这个时候就需要vscodeapi了。

回到我们的extension.ts文件中

  • vscode.window[13] 也就是窗口
  • window.activeTextEditor[14]:获取当前的编辑窗口
  • activeTextEditor.selection[15]: 获取选中区域对象,它里面包含了选中的起始位置
  • vscode.Position[16]: 这玩意儿是二维的,需要你传入行数和列数,是不可变的(immutable)。
  • vscode.Range[17]: 创建一个范围,我们需要传入两个Position对象作为startend
  • editor.document[18].getText: 获取编辑窗口中选中的范围,接收一个Range

最终拿到的text就是我们通过鼠标滑出来的区域。

可以打个log看下是否正常拿到内容

可以看到正常拿到了。

然后我们来解析这块区域的内容


解析内容

这里就要借助我们的babel了。

在刚刚的代码基础上,加上上面的代码。

这里我简单的解释下:

  • parser.parse(textTrim):将文本转换成AST
  • traverse.default(ast):遍历整棵AST Tree,我在遍历过程中监听了几个场景:
    • ObjectProperty:对象属性,这里面有我们的type、data、url以及function/arrow function,这个functionarrow function指的是比如/error: function () {}/error: () =>{}这两种写法,它们也算是ObjectProperty
    • ObjectMethod:这个其实也是方法,不过是error () {}这种写法。和上面函数的写法没差别,至于为什么要做区分,我个人觉得应该是和其他语言里的”关联函数“和函数的区别吧,用methodfunction区分。
  • generator.default:将ast转换为字符串。

这个过程中我们拿到了几乎所有的内容。


支持额外配置

我们还可以提供插件配置入口给使用者,这样用户可以通过setting.json的方式做一些不同的行为

  • reg_str:一个二维数组,元素类型为:[string, string],第一个为一个正则表达式,第二个则是替换的内容。这样用户就可以自定义哪些内容自动替换成另一些内容。
  • axios_path:你的axios路径,你可以配置成import xx的方式,这样就不需要手动导入了。
  • axios_aliasaxios的别名,比如你如果是直接将axios放到window上或者this上,那么你这个时候就可以改成this.axios,这样就不需要手动调整了,也不需要导入了。
  • remove_fn_wrapper:是否需要用函数包裹你的内容
  • vscode.workspace[19].getConfiguration: 获取工作区的配置内容。

转换

现在我们拿到用户自定义配置内容和数据了,这个时候就可以进行转换了。

其实这里应该搭配上babel/template的,但是我图省事就不这么做了。

extension.ts文件下面创建一个template.ts文件

可读性挺差,但是很好理解,就是一个简单的字符串模板。

没啥好说的,也没啥技术含量。

接着导入到extension.ts

  • textEditor.edit:它接收一个回调,回调的参数会传入一个editBuilder[20]

我们通过这个editBuilder来将我们最新的代码替换原来的代码

现在就ok了,我们来试下

顺便加点配置

大功告成~


发布

既然完成了,那接下来自然就是发布。

这一步稍微有那么点复杂。

首先我们需要去到Azure DevOps Services | Microsoft Azure

然后创建一个账户

注册完之后到个人页面找到这个

然后创建一个新的token

然后保存好你的token,接下来要用来登陆的

然后回到我们的项目中,新开个终端

这个vscevscode发布插件的工具

你可以试下vsce --version测试下是否安装成功

然后登录

然后会让你输入token,你把刚才保存的token复制过来输入即可。

登录成功后就可以发布了

另外如果你是多次发布,你需要修改你的版本号,对应package.json里的version,你可以使用

  • vsce publish patch:表示更新一个小版本,比如1.0.0 -> 1.0.1
  • vsce publish minor:表示更新一个中版本,即1.0.0 -> 1.1.0
  • vsce publish major:更新一个大版本,即1.0.0 -> 2.0.0

不过在发布前,你一般可以同步你的个人信息或者github项目地址

比如:

注意这里的icon,表示你的插件的图标,放在根目录即可,最好是128 * 128大小的。

另外最好补充下README,因为这个将作为你的插件的教程。

发布出去后你可以去到https://marketplace.visualstudio.com/manage发布市场去看下自己的插件是否发布成功了。

那么到这里,一个完整的流程就结束了。


总结

莫得

补充

另外有一点需要注意

创建项目的时候最好看下engines的版本,如果大于当前vscode的版本,那就是有问题的,你需要手动调整到适应的版本

参考

  1. ^yo https://www.npmjs.com/package/yo
  2. ^generator-code https://www.npmjs.com/package/generator-code
  3. ^activationEvents https://code.visualstudio.com/api/references/activation-events
  4. ^contributes https://code.visualstudio.com/api/references/contribution-points
  5. ^contributes.colors https://code.visualstudio.com/api/references/contribution-points#contributes.colors
  6. ^registerCommand https://code.visualstudio.com/api/references/vscode-api#commands.registerCommand
  7. ^babel https://babeljs.io/
  8. ^String.prototype.replaceAll https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll
  9. ^commands https://code.visualstudio.com/api/references/contribution-points#contributes.commands
  10. ^menus https://code.visualstudio.com/api/references/contribution-points#contributes.menus
  11. ^keybinds https://code.visualstudio.com/api/references/contribution-points#contributes.keybindings
  12. ^@babel/template https://babeljs.io/docs/babel-template
  13. ^vscode.window https://code.visualstudio.com/api/references/vscode-api#window
  14. ^activeTextEditor https://code.visualstudio.com/api/references/vscode-api#window
  15. ^TextEditor.Selection https://code.visualstudio.com/api/references/vscode-api#Selection
  16. ^vscode.Position https://code.visualstudio.com/api/references/vscode-api#Position
  17. ^vscode.Range https://code.visualstudio.com/api/references/vscode-api#Range
  18. ^textDocument https://code.visualstudio.com/api/references/vscode-api#TextDocument
  19. ^vscode.workspace https://code.visualstudio.com/api/references/vscode-api#workspace
  20. ^textEditOrEdit https://code.visualstudio.com/api/references/vscode-api#TextEditorEdit

编辑于 2023-08-07 14:07・IP 属地广东