开发一个 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】协议,转载请保留原文出处及本版权声明。
评论