开发一个 PicGo 插件

前言
最近在搞 typora 的文档云同步功能,在网上看了一些文章有提到 PicGo 图片上传工具,于是放到一起折腾了一下,但 PicGo 默认只支持 7 种图床,搭配插件也无法满足我的需求,于是便想着开发一个高度自定义的上传插件。
关于 PicGo 插件开发,详细信息可看官方文档 PicGo-Core,本文只实现了 Uploader 上传器组件,其他组件还有
- Transformer 
- beforeTransformPlugins 
- beforeUploadPlugins 
- afterUploadPlugins 
如有需要,读者可查看官方文档自己实现,本文不作讨论。
项目基本架构
根据官方描述,一个合法的 PicGo 插件应该是一个 npm 包,它的最简单的结构如下
也可以使用 npx webpack init 命令快速生成符合条件的完整项目环境,其中 package.json 文件应添加以下字段
 
 为让插件能够被 PicGo 识别,name 需要写成指定格式: picgo-plugin-xxx。
插件实现
插件注册
PicGo 中图片上传对应的组件是 Uploader,它被实现为一个函数,接收一个 PicGo 实例作为参数,并返回一个包含 register 和 uploader 字段的对象;其中,register 是一个注册器函数,uploader 则告诉 PicGo 这个 Uploader 的名字,基本格式如下:
在 register 中我们需要调用 PicGo 提供的 Uploader 注册器注册我们的 Uploader 插件,注册器接收一个插件 id 和一个配置对象,配置对象必须实现一个 handle 方法,这个方法就是主要的上传逻辑,代码大概如下:
用户配置
我们先忽略上传的主要逻辑,先完善用户能够自定义的配置部分;PicGo 允许我们定义一个 config 函数,函数应该返回与当前组件有关的问题数组,PicGo 会根据这个问题数组渲染对应的配置项,比如:
那么渲染出来的配置项就长这样
 
 通过配置项我们将部分数据交由用户输入,实现自定义上传配置的操作,但这样的数据是死数据,如果我们需要动态数据时要怎么办呢?
一个简单的想法是直接修改插件,另一个想法是定义一些关键字,用户配置了关键字时我们就构造出相应的数据,比如用户定义了 timestamp 字段,我们就在上传时构建一个时间戳出来。
这两个办法都能够解决我们的问题,但是我不用:smirk:,我们为什么不允许用户自定义脚本,在每次上传时调用用户脚本获取到他需要的参数呢。
这个想法是好的,但我们需要考虑一个问题:安全性。我们不知道用户的脚本是否是安全可靠的,为此,我们需要一个安全的环境来执行用户的脚本,也就是 sandbox (沙箱)。
这里我用到了在网上看到的一遍讲解 sandbox 的文章 为 Node.js 应用建立一个更安全的沙箱环境 作者开发的库 Safeify,这个库允许我们创建沙箱环境并限制 sandbox 内部能够访问的上下文,并配置代码执行的超时时长、cpu 资源的分配比、内存的分配比等等,它的简单使用如下:
安全的问题解决了,那我们怎么获取到用户的脚本呢,让用户复制粘贴并不是很友好,不过好在 PicGo 还提供了 guiMenu 配置,guiMenu 的格式如下:
渲染后大概长下面这样
 
 通过 guiMenu 能够获取到用户选择的文件路径,然后使用 fs 模块读取用户脚本并使用 PicGo 实例的 saveConfig 方法即可保存用户脚本至 PicGo 配置文件里,获取 PicGo 配置可使用 PicGo 实例的 getConfig 方法。
上传器
上传的逻辑都是大同小异的,主要是遍历 PicGo 实例的 output 数组,获取其中的图片数据,整合用户配置,最后发起请求,这部分的代码可以直接 CV PicGo 插件列表 中其他插件开发者的代码,这里不做详述。
这里我自己实现了一个插件 free-uploader,感兴趣的可以看看。
目前这个插件个人觉得可以优化的点有:
- PicGo提供了- failed事件,在生命周期中出现错误或上传失败时会触发这个事件,可以将失败处理统一挪动到这个事件中并自定义通知用户。
- PicGo提供了- remove事件,用户删除本地图片数据时会触发,因为用户所使用的图床不一定支持删除接口,可以把这部分交由用户实现以达到同步删除的目的。
- 因为采用了动态脚本的方式,我们甚至可以提供图片数据,让用户执行压缩,水印添加等操作,也可以提供请求相关函数以支持上传除图片外的数据,如视频。 
--end
版权声明: 本文为 InfoQ 作者【yuanyxh】的原创文章。
原文链接:【http://xie.infoq.cn/article/14921edfbb0e8d869bdaa36b1】。
本文遵守【CC BY-NC】协议,转载请保留原文出处及本版权声明。








 
    
 
				 
				 
			


评论