Skip to content

插件配置字段详解

PicGo 的 Uploader / Transformer / Plugin 三类组件都可以通过 config(ctx) 方法暴露一组字段。这组字段在 CLI 端会被交给 inquirer.js 渲染成命令行提示,在 GUI 端会被渲染成可视化表单。

一个最小示例

下面是一个 GitLab Uploader 风格的简化例子,覆盖了几个最常用的字段类型:

js
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:

js
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

通用字段

所有字段类型都支持下面这几个属性:

字段类型说明
namestring必填。字段名,会作为最终配置对象里的 key
type'input' | 'password' | 'list' | 'checkbox' | 'confirm' | 'editor'必填。字段类型,决定如何渲染
requiredboolean是否必填。GUI 会在表单顶部加红星;CLI 会在用户输入空值时阻止继续
defaultunknown | ((answers) => unknown)默认值。也可以写成函数,见 联动字段
aliasstringGUI 表单里的字段标题。CLI 不展示。如果不写,GUI 会退回到 name
messagestringCLI 端的 prompt 文案 / GUI 端的 input placeholder
tipsstringGUI 字段标题旁的 ❓ tooltip 内容,支持 Markdown,会被安全渲染。CLI 不展示

提示

aliastips 都是 picgo 的扩展字段,inquirer 原生没有,CLI 端会被忽略。

字段类型

input —— 单行文本

普通的字符串输入。

js
{
  name: 'bucket',
  type: 'input',
  alias: 'Bucket',
  default: '',
  required: true
}

password —— 密文

input 一样接收字符串,但 GUI 端默认遮蔽显示(提供眼睛按钮切换可见),CLI 端 inquirer 的输入也不回显。

js
{
  name: 'secretKey',
  type: 'password',
  alias: 'SecretKey',
  default: '',
  required: true
}

list —— 单选下拉

从一组选项里选一个。choices 必填。

js
{
  name: 'region',
  type: 'list',
  alias: '区域',
  choices: ['us', 'eu', 'asia'],
  default: 'us',
  required: true
}

choices 可以是字符串数组(label 和 value 相同),也可以是对象数组:

js
choices: [
  { name: '北美', value: 'us' },       // GUI 显示"北美",存储值是 'us'
  { name: '欧洲', value: 'eu' },
  { name: '亚洲', value: 'asia' }
]

checkbox —— 多选

多选 list。default 通常是一个数组。

js
{
  name: 'options',
  type: 'checkbox',
  alias: '处理选项',
  choices: [
    { name: '瘦身', value: 'slim', checked: true },  // checked 表示初始勾选
    { name: '水印', value: 'watermark' }
  ],
  default: ['slim']
}

checked 字段只对 checkbox 生效,列表初次渲染时会勾上。

confirm —— 是 / 否开关

布尔值,GUI 端渲染成 Switch。

js
{
  name: 'slim',
  type: 'confirm',
  alias: '图片瘦身',
  confirmText: '开启',     // 切换到 true 时的标签
  cancelText: '关闭',      // 切换到 false 时的标签
  tips: '开启后会对上传的图片进行压缩处理',
  default: false
}

confirmText / cancelText 仅 confirm 类型有效。

editor —— 多行文本 3.0.0+

需要让用户输入多行文本的场景就用这个,比如 API Keys 列表、自定义的转换/压缩脚本、模板片段等。字段最终的值仍然是 string,里面可以包含 \n,picgo 不做二次处理。

js
{
  name: 'script',
  type: 'editor',
  alias: '压缩脚本',
  required: true,
  message: '请输入压缩流程脚本(多行)'
}

两端的行为:

  • CLI:inquirer 6 原生 editor 类型,会按 VISUALEDITOR → 平台默认编辑器(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+

如果你希望某个字段的 choicesdefault 随其它字段的当前值动态变化——比如先选 region 再决定 bucket 列表——可以把 choicesdefault 写成函数,并通过 dependsOn 声明依赖关系。

choicesdefault 都支持以下两种形态:

  • 静态值:和原来一样,数组或字面量
  • 函数:(answers) => ...answers 是当前已知字段值的快照(Record<string, unknown>

dependsOn 是一个字符串数组,列出本字段在求值时依赖哪些字段的 name。它主要给 GUI 使用——GUI 据此监听某个字段值变化并触发刷新;CLI 这边由 inquirer 按 prompt 顺序自然累积 answers,所以 dependsOn 在 CLI 路径里只是元数据,不参与求值。

一个最小的两级联动例子(region → bucket):

js
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 / defaultdependsOn 一起用更清晰,但你也可以只用函数不声明 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 里的临时字段不会写进配置文件,所以你不用担心联动过程中临时产生的字段污染配置。