插件配置字段详解
PicGo 的 Uploader / Transformer / Plugin 三类组件都可以通过 config(ctx) 方法暴露一组字段。这组字段在 CLI 端会被交给 inquirer.js 渲染成命令行提示,在 GUI 端会被渲染成可视化表单。
一个最小示例
下面是一个 GitLab Uploader 风格的简化例子,覆盖了几个最常用的字段类型:
const uploaderConfig = ctx => {
// 从已存配置里读一次,作为本次表单的初始值
const userConfig = ctx.getConfig('picBed.gitlab') || {}
return [
{
name: 'host', // 字段名,将作为最终配置的 key
type: 'input', // 单行文本
alias: 'Host', // GUI 表单里的字段标题
default: userConfig.host || 'https://gitlab.com',
required: true
},
{
name: 'token',
type: 'password', // 密文输入
alias: 'Token',
default: userConfig.token || '',
required: true
},
{
name: 'visibility',
type: 'list', // 下拉/单选
alias: '可见性',
choices: ['public', 'private'],
default: 'private',
required: false
}
]
}写好字段后,按维度的不同方式把 config 暴露给 picgo:
const handle = ctx => ctx
const uploaderConfig = ctx => [ /* Uploader 字段,见上一段 */ ]
const transformerConfig = ctx => [ /* Transformer 字段 */ ]
const pluginConfig = ctx => [ /* Plugin 自身字段 */ ]
module.exports = ctx => {
const register = () => {
// Uploader 的 config 跟着 handle 一起注册进 helper.uploader
ctx.helper.uploader.register('gitlab', {
handle,
config: uploaderConfig
})
// Transformer 的 config 同理,注册进 helper.transformer
ctx.helper.transformer.register('gitlab', {
handle,
config: transformerConfig
})
}
return {
register,
uploader: 'gitlab', // 把 Uploader 名暴露给 picgo,否则不能被自动选用
transformer: 'gitlab', // Transformer 同理
config: pluginConfig // Plugin 自身的 config 直接挂在导出对象上
}
}三个维度的 config 都返回字段数组,结构和写法完全一样,区别只在于挂在哪里、配置最终被写到 picgo 配置文件的哪个 key(具体见 config 方法)。
提示
ctx.getConfig('picBed.<name>') 是常用的"读已存配置回填表单"模式。Uploader 的配置存在 picBed.<name> 下,Transformer 的存在 transformer.<name> 下,Plugin 自身的存在 <pluginFullName> 下(具体见 config 方法)。
picgo-core 内置 Uploader 的完整真实示例可以参考 tcyun.ts。
通用字段
所有字段类型都支持下面这几个属性:
| 字段 | 类型 | 说明 |
|---|---|---|
name | string | 必填。字段名,会作为最终配置对象里的 key |
type | 'input' | 'password' | 'list' | 'checkbox' | 'confirm' | 'editor' | 必填。字段类型,决定如何渲染 |
required | boolean | 是否必填。GUI 会在表单顶部加红星;CLI 会在用户输入空值时阻止继续 |
default | unknown | ((answers) => unknown) | 默认值。也可以写成函数,见 联动字段 |
alias | string | GUI 表单里的字段标题。CLI 不展示。如果不写,GUI 会退回到 name |
message | string | CLI 端的 prompt 文案 / GUI 端的 input placeholder |
tips | string | GUI 字段标题旁的 ❓ tooltip 内容,支持 Markdown,会被安全渲染。CLI 不展示 |
提示
alias 和 tips 都是 picgo 的扩展字段,inquirer 原生没有,CLI 端会被忽略。
字段类型
input —— 单行文本
普通的字符串输入。
{
name: 'bucket',
type: 'input',
alias: 'Bucket',
default: '',
required: true
}password —— 密文
和 input 一样接收字符串,但 GUI 端默认遮蔽显示(提供眼睛按钮切换可见),CLI 端 inquirer 的输入也不回显。
{
name: 'secretKey',
type: 'password',
alias: 'SecretKey',
default: '',
required: true
}list —— 单选下拉
从一组选项里选一个。choices 必填。
{
name: 'region',
type: 'list',
alias: '区域',
choices: ['us', 'eu', 'asia'],
default: 'us',
required: true
}choices 可以是字符串数组(label 和 value 相同),也可以是对象数组:
choices: [
{ name: '北美', value: 'us' }, // GUI 显示"北美",存储值是 'us'
{ name: '欧洲', value: 'eu' },
{ name: '亚洲', value: 'asia' }
]checkbox —— 多选
多选 list。default 通常是一个数组。
{
name: 'options',
type: 'checkbox',
alias: '处理选项',
choices: [
{ name: '瘦身', value: 'slim', checked: true }, // checked 表示初始勾选
{ name: '水印', value: 'watermark' }
],
default: ['slim']
}checked 字段只对 checkbox 生效,列表初次渲染时会勾上。
confirm —— 是 / 否开关
布尔值,GUI 端渲染成 Switch。
{
name: 'slim',
type: 'confirm',
alias: '图片瘦身',
confirmText: '开启', // 切换到 true 时的标签
cancelText: '关闭', // 切换到 false 时的标签
tips: '开启后会对上传的图片进行压缩处理',
default: false
}confirmText / cancelText 仅 confirm 类型有效。
editor —— 多行文本 3.0.0+
需要让用户输入多行文本的场景就用这个,比如 API Keys 列表、自定义的转换/压缩脚本、模板片段等。字段最终的值仍然是 string,里面可以包含 \n,picgo 不做二次处理。
{
name: 'script',
type: 'editor',
alias: '压缩脚本',
required: true,
message: '请输入压缩流程脚本(多行)'
}两端的行为:
- CLI:inquirer 6 原生
editor类型,会按VISUAL→EDITOR→ 平台默认编辑器(Unix 上是vi/nano,Windows 上是notepad)的优先级调起外部编辑器,用户保存退出即提交完整原文,picgo-core 不会 trim 或加工。 - GUI:渲染成
<Textarea>,随着内容自动撑高,用户可以拖右下角手柄手动调整高度。
提示
Windows 用户如果默认 notepad 体验不佳,可以设置 EDITOR=code -w 之类的"等待模式"编辑器(注意要带 -w 让 CLI 阻塞等 GUI 编辑器关掉再返回)。这是 inquirer / external-editor 的固有行为,PicGo 不参与解析。
联动字段 3.0.0+
如果你希望某个字段的 choices 或 default 随其它字段的当前值动态变化——比如先选 region 再决定 bucket 列表——可以把 choices 或 default 写成函数,并通过 dependsOn 声明依赖关系。
choices 和 default 都支持以下两种形态:
- 静态值:和原来一样,数组或字面量
- 函数:
(answers) => ...,answers是当前已知字段值的快照(Record<string, unknown>)
dependsOn 是一个字符串数组,列出本字段在求值时依赖哪些字段的 name。它主要给 GUI 使用——GUI 据此监听某个字段值变化并触发刷新;CLI 这边由 inquirer 按 prompt 顺序自然累积 answers,所以 dependsOn 在 CLI 路径里只是元数据,不参与求值。
一个最小的两级联动例子(region → bucket):
const config = ctx => [
{
name: 'region',
type: 'list',
alias: '区域',
choices: ['us', 'eu', 'asia'],
default: 'us',
required: true
},
{
name: 'bucket',
type: 'list',
alias: 'Bucket',
dependsOn: ['region'],
// 用户选了 region 之后,这里能拿到最新的 answers.region
choices: (answers) => {
if (answers.region === 'eu') {
return ['eu-west-prod', 'eu-central-prod']
}
if (answers.region === 'asia') {
return ['asia-sg-prod', 'asia-tk-prod']
}
return ['us-east-prod', 'us-west-prod']
},
required: true
}
]提示
你的函数要兼容 answers === {} 的情况——首次序列化 schema(GUI 端展示初始表单)时,answers 是空对象。给前序字段一个合理的兜底就行,比如上面 answers.region 找不到时落到 us 分支。
通常来说函数式 choices / default 跟 dependsOn 一起用更清晰,但你也可以只用函数不声明 dependsOn——CLI 一样能跑(inquirer 自己求值),不过 GUI 端就不知道该在什么时候刷新,下拉框只会显示首次序列化时的结果。
GUI 端表单值合并和刷新的行为见 GUI 插件开发 - 联动字段。
异常处理
字段级隔离是个一致的策略——一个字段坏了,其它字段不受影响。具体来说:
choices函数抛异常 → 该字段choices退化为[](GUI 下拉框空状态、CLI 用户无可选项)default函数抛异常 → 该字段default退化为undefined- 都会通过
ctx.log.warn记录字段名和错误信息
所以你写函数式 choices / default 时不需要写防御式 try/catch,picgo 会兜底。不过你最好还是自己处理掉异常。
配置文件存储路径
参考 config方法 的 JSON 示例。简短复述一下:
- Uploader:
picBed.<uploaderName>.<fieldName> - Transformer:
transformer.<transformerName>.<fieldName> - Plugin(自身配置):
<pluginFullName>.<fieldName>,存在配置文件根级
GUI 端在保存时会用当前 schema 过滤掉孤儿键,不在 schema 里的临时字段不会写进配置文件,所以你不用担心联动过程中临时产生的字段污染配置。
