时光不负,创作不停,本文正在参加2022年中总结征文大赛
背景
工欲善其事,必先利其器。本人近期一直在使用Vuepress2进行帮助文档的撰写和修改,由于该帮助文档有超过100个页面,且分别列在几个不同的目录下,那么就产生了两个痛点:
- 文档writer不是技术出身,每次在命令行里打
cd project-name(因为同一工程下还有其他文件夹负责保存产品新特性的PDF)和npm run docs:dev都很难受,有时问我怎么跑不起来,一看是没有cd进入相应目录; - Markdown文件太多,当我想修改目录A下的x文件时都要去跑起来的界面里看效果,为什么不直接装markdown预览插件呢,因为预览效果与实际的渲染结果有一定的差距。
那么我灵机一动,就想能不能实现类似open-in-browser插件的功能呢,直接在Markdown文件中右击或者在资源管理器中右击打开对应的页面。
如上图所示,对于HTML文件,open-in-browser可以在右击菜单中显示这两个选项。
初识Visual Studio Code Extension
对于一项新的技术,毫无疑问学习它的最简单的办法是去找它的官方文档,跟着它我们可以很快把项目框架建出来。在开发过程中遇到什么问题的话我们也可以查阅open-in-browser的源代码。
根据教程:
-
首先要安装 Yeoman 和 VS Code Extension Generator,运行
npm install -g yo generator-code即可 -
在合适的目录内打开终端,运行
yo code,选择想要构建的工程,此处选择第一个
- 给项目命名、添加描述,是否初始化git仓库,是否用webpack,用npm还是yarn等,按照需求进行选择即可。
项目最终如图所示:
主要关注extension.ts和package.json两个文件。点开前者,按F5即可启动调试模式
在主程序代码中↓,activate()函数是当插件被激活时调用,log里的内容会显示在调试控制台中且只会在激活时执行一次,disposable负责注册命令,该命令只会在插件执行时调用,helloworld.helloworld点号前的是我们的插件名称,点号后面的是当前命令名称,我们可以在package.json文件中找到它。
命令要在activationEvents和commands都定义一次。在contributes中写的内容被称为Contribution Points,这里可以添加一些字段以拓展插件功能,比如图标、主题、案件绑定等,之后细说。
规划插件
在背景中我们已经介绍了希望实现了功能,现在也了解了一个插件是如何工作的,那么我们就可以来规划一下项目的运行流程:
- 让用户在
settings中定义他目前使用的端口port、base(vuepress的config.ts中的属性)、命令command - 获得当前打开的md文件的路径,比如
C:/Users/UserA/Desktop/project-name/.vuepress/docs/dirA/A.md,那么运行vuepress之后A.md就会在http://localhost:${port}/${base}/dirA/A.html中呈现,那么只要将文件路径用docs/分割,再把.md替换成.html就能获得dirA/A.html,再获取port、base进行字符串拼接即可获得最终的可访问的url - 检测当前
port是否被占用,若占用则说明用户已经开启了服务,那么直接打开url即可。若没被占用,就在终端里执行定义好的command并打开url,同时也要把终端显示出来,不能让它默默在背后运行
tips:我一开始也不知道如何调用终端、获取settings等,都是通过Google搜索出来的,比如搜
how to display terminal in vscode extension
StackOverflow上通常都会有很好的答案
开始编写
package.json
首先在package.json中的contributes-menus里设置好两个右键指令(右击打开的文件窗口或资源管理器中的文件),此处可以在官方APIContribution Points中找到详细表述。
editor/context指在当前打开的文件右击,explorer/context指资源管理器中右击,让两者只有当文件为markdown时才能生效,command分别写上主程序里registerCommand中定义的命令名称,group可以让该右键菜单中的这行与谁归为一组,比如下图是三组不同的命令
然后在configuration中写上用户打开settings后可以定义的字段,API文档链接
最后在activationEvents和commands把两个命令写进去即可,最终完成了package.json的编写。
extension.ts和utils.ts
为了保持主程序的整洁,我把一些工具类的函数提取到了utils.ts中,比如获得用户定义的settings、获取当前页面uri、获取资源管理器中某文件uri、裁切uri、拼接字符串、运行命令等,大家看代码就懂了:
在extension.ts中,我们只要按部就班地使用这些函数即可,检测端口用的是tcpPortUsed.check(port, ip)方法,注意这个方法返回promise,所以要使用async-await关键字。打开页面使用open库,传入网址就会使用默认浏览器打开它。
最后把两个命令推入就大功告成啦:
按F5测试一下,成功!
我也是第一次写插件,仓库在SummerGua/OpenThisVuepressPage,欢迎大家批评指正:)