拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

PicGo 贡献指南:掌握 Electron 三进程架构、i18n 多语言扩展与规范提交流程

PicGo 贡献指南:掌握 Electron 三进程架构、i18n 多语言扩展与规范提交流程
  • 桌面应用
  • 开发工具
  • 插件系统

【免费下载链接】PicGo

:rocket: The Ultimate Image Uploader for Efficient Creators. Supports Obsidian, Typora, VS Code etc. and 60+ image hosting services (S3, GitHub, Cloudflare R2, Imgur, Aliyun OSS...). Paste, upload, done.

项目地址:https://gitcode.com/gh_mirrors/pi/PicGo
点击查看免费下载

本篇技术指南以 PicGo 官方贡献文档(CONTRIBUTING_EN.md)为骨架,结合当前仓库源码,系统讲解贡献者从零开始搭建开发环境、遵循目录边界编写代码、扩展多语言文件以及按规范提交代码的完整流程。读完本文,你将掌握 PicGo 主进程 / 渲染进程 / 共享层的代码放置规则、跨进程事件与全局类型的集中管理方式,以及一套可直接照做的 i18n 语言文件新增与更新步骤。

一、环境准备:安装依赖与启动项目

PicGo 的贡献流程第一步是搭建本地开发环境。官方文档指定的包管理器是 yarn,安装依赖后启动开发模式:

yarn install

安装完成后,通过以下命令启动项目:

yarn dev

从当前仓库 package.json 的 scripts 可以看到,dev脚本实际执行的是electron-vite dev,它由 Electron、Vite 与构建插件共同驱动,会同时监听主进程(src/main)、预加载(src/preload)与渲染进程(src/renderer)的代码变更。如果你使用的是 pnpm 工作区,也可以执行pnpm install与pnpm dev,两者等价地指向同一套 electron-vite 开发流程(AGENTS.md 中明确注明 npm install 不受支持)。

启动成功后,你就拥有了一个可实时热更新的 PicGo 桌面端开发环境,可以开始编写或修改代码。

二、代码目录边界:主进程、渲染进程与共享层的放置规则

PicGo 是一个 Electron + 前端框架构建的桌面应用,贡献文档对代码归属提出了严格的目录约束,这是理解整个项目组织方式的核心:

  • 只与 Electron 主进程相关的代码:放入src/main目录;
  • 只与渲染进程相关的代码:放入src/renderer目录;
  • 两个进程都能使用的代码:放入src/universal目录。

关键约束:渲染进程不具备 Node.js 能力。因此,任何渲染进程需要使用 Node.js 模块(文件系统、剪贴板、原生对话框等)的代码,都必须通过src/main/events/picgoCoreIPC.ts中注册的 IPC 事件交由主进程处理,而不是在渲染进程里直接requireNode 模块。

这条规则的底层原因在于 Electron 的安全模型:渲染进程运行在浏览器环境(且 PicGo 启用了上下文隔离),只有主进程拥有完整的 Node.js 运行时。仓库里的 IPC 总线 src/main/events/picgoCoreIPC.ts 正是这一架构的落地实现——文件底部统一的listen()方法(picgoCoreIPC.ts#L319-L332)集中注册了所有事件处理器,例如:

  • 配置读写:PICGO_GET_CONFIG/PICGO_SAVE_CONFIG(内部调用picgo.getConfig(key)与picgo.saveConfig(data));
  • 相册数据库操作:PICGO_GET_DB、PICGO_INSERT_DB、PICGO_UPDATE_BY_ID_DB等,经由AlbumDB.getInstance()完成 lowdb 的增删改查;
  • 剪贴板写入:PASTE_TEXT会根据settings.pasteStyle与settings.customLink配置,通过pasteTemplate生成 Markdown / HTML / URL 等格式的文本并写入剪贴板。

从源码结构看,这条约定已经渗透到仓库的方方面面:渲染进程侧的 IPC 适配器 全部通过useIPC等桥接层向主进程发起调用,而不是直接触碰 Node API。因此,新增功能时判断“代码放哪里”的第一标准就是:它需不需要访问 Node.js 能力?

三、跨进程事件名:统一收敛到 constants.ts

由于主进程与渲染进程之间通过 IPC 通信,事件名必须全局唯一、集中管理,否则极易出现拼写错误与命名冲突。贡献文档要求:

所有跨进程事件名请统一添加在src/universal/events/constants.ts。

查看 src/universal/events/constants.ts,可以发现它就是一个纯常量导出模块,覆盖了窗口控制(MINIMIZE_WINDOW、MAXIMIZE_WINDOW、CLOSE_WINDOW)、剪贴板(CLIPBOARD_WRITE_TEXT)、i18n(GET_CURRENT_LANGUAGE、SET_CURRENT_LANGUAGE)、相册数据库(PICGO_GET_DB、PICGO_REMOVE_BY_ID_DB)等全部事件名(constants.ts#L1-L53)。

为什么放在src/universal而不是两处各写一份?因为事件名是主进程与渲染进程的“通信协议”,共享层的定位保证了主进程ipcMain.on(constant)与渲染进程ipcRenderer.send(constant)引用的是同一个常量值,从根本上杜绝了"两边字符串不一致导致静默失效"的经典 IPC 事故。这也是 picgoCoreIPC.ts 顶部通过import { ... } from '#/events/constants'引用这些常量的原因——事件注册方与触发方共用同一份定义。

四、全局类型定义:types 目录与 enum 的强制归位

TypeScript 是 PicGo 的核心语言,为了让主进程与渲染进程共享同一套数据结构,贡献文档要求:

所有全局类型定义放在src/universal/types/下;如果是enum,必须放在src/universal/types/enum.ts。

打开 src/universal/types/enum.ts 可以看到项目里所有跨进程使用的枚举都被收敛在此处,例如:

  • IPicGoHelperType(enum.ts#L8-L14):定义了uploader、transformer、beforeUploadPlugins、beforeTransformPlugins、afterUploadPlugins五类 helper 类型,与 PicGo 核心的上传流水线一一对应;
  • IPasteStyle(enum.ts#L16-L22):markdown、HTML、URL、UBB、Custom五种粘贴格式,直接驱动 picgoCoreIPC.ts 中PASTE_TEXT的模板生成逻辑;
  • IWindowList(enum.ts#L24-L30):SETTING_WINDOW、TRAY_WINDOW、MINI_WINDOW等窗口枚举,被窗口管理器windowManager引用;
  • IRPCActionType(enum.ts#L54-L122):渲染进程通过 RPC 触发主进程动作的完整清单,覆盖配置、插件、版本检查、工具箱、系统与 PicGo Cloud 等全部能力。

与事件名同理,把枚举和类型放进src/universal/types/是为了让两个进程引用同一份类型定义,保证 IPC 载荷的结构在编译期即可校验。新增跨进程数据结构时,请遵循这一约定,不要散落在各自的进程目录里。

五、i18n 多语言扩展:三步新增一种语言

PicGo 面向全球用户,多语言是贡献的高频场景。贡献文档给出了新增语言的完整流程,下面结合仓库源码逐条展开。

5.1 创建语言文件并声明显示名

在public/i18n/目录下创建对应语言的 YAML 文件,例如新增简体中文可命名为zh-Hans.yml。文件内容参考已存在的 zh-CN.yml 或 en.yml 编写。

语言文件的第一行必须是LANG_DISPLAY_LABEL,PicGo 会通过它在设置界面中向用户展示该语言的名称。以 en.yml 为例:

LANG_DISPLAY_LABEL: "English"

而zh-CN.yml中对应的值是简体中文。语言文件采用扁平的KEY: 文案结构,文案中支持${变量}插值,例如CONFIG_THING: Config ${c}、ALBUM_CLOUD_IMPORT_SUCCESS: Successfully imported ${num} items to cloud album。在 src/main/i18n/index.ts 的I18nManager中,所有语言文件通过yaml.load被解析为ILocales类型对象,并依据getStaticPath('i18n')找到运行时路径;若目标语言文件缺失或解析失败,会自动回退到默认语言en(i18n/index.ts#L28-L53),这正是LANG_DISPLAY_LABEL与文件命名必须严格一致的原因。

5.2 在共享层注册默认语言

新建语言文件后,需要在src/universal/i18n/index.ts中将其注册为可选项。查看 src/universal/i18n/index.ts 可以看到内置语言列表builtinI18nList:

export const builtinI18nList: II18nItem[] = [{ label: '简体中文', value: 'zh-CN' }, { label: '繁體中文', value: 'zh-TW' }, { label: 'English', value: 'en' }, { label: '한국어', value: 'ko' }, { label: '日本語', value: 'ja' }]

其中label必须与语言文件中的LANG_DISPLAY_LABEL值保持一致(例如新增zh-Hans.yml时 label 填简体中文),value是语言文件名(不含扩展名,例如zh-Hans)。注册后,I18nManager的addI18nFile(file, label)与languageListgetter(i18n/index.ts#L75-L77)就会把新语言纳入设置界面的语言下拉列表。

5.3 更新语言文件后生成语言类型定义

贡献文档特别强调:如果是对已有语言文件进行更新,更新后务必运行yarn gen-i18n,确保能生成正确的语言定义文件。

需要说明的是,当前仓库的实际情况是:类型定义文件的生成已经由 Vite 插件自动化完成。仓库根目录的 AGENTS.md 明确指出:"i18n type files are auto-generated by the Vitei18nTypesPluginwhenpublic/i18n/*.ymlchanges. Do not add or rely on a manualgen-i18nstep." 具体实现见 scripts/vite-plugin-i18n-types.ts:该插件在buildStart、文件热更新等时机读取public/i18n/en.yml的顶层键,自动生成两份类型声明:

  • src/universal/types/i18n.d.ts:生成ILocales接口(所有翻译键的联合类型);
  • src/renderer/i18n/i18next.d.ts:为 i18next 声明CustomTypeOptions,让渲染进程拿到完整的键名类型提示。

因此,无论你执行文档中提到的yarn gen-i18n,还是依赖 Vite 插件的自动生成,最终效果都是让翻译键获得编译期检查——一旦在代码里写错键名,TypeScript 会直接报错。新增翻译键时,务必保证en.yml、zh-CN.yml、zh-TW.yml等所有语言文件同步补齐,避免出现某语言缺失键导致回退英文的情况。

六、提交代码:清理调试痕迹并使用规范提交工具

贡献文档对代码提交提出了两条硬性要求,这也是通过 CI 检查的前置条件。

6.1 提交前自检:无多余注释与调试代码

请检查代码没有多余的注释、console.log等调试代码。

这一步与仓库的 ESLint 配置相呼应。package.json 中提供了yarn lint(eslint --ext .js,.jsx,.ts,.tsx,.vue src/)与yarn lint:fix脚本,仓库还配置了lint:dpdm用于在src/中检测循环依赖(--exit-code circular:1)。提交前建议执行yarn check(即tsc类型检查 + lint 修复),确保代码整洁且通过类型系统校验。

6.2 使用 PicGo 代码提交规范工具

提交代码前,请执行命令git add . && yarn cz,唤起 PicGo 的代码提交规范工具(PicGo/bump-version),通过该工具提交代码。

从 package.json 可以看到,cz脚本映射到git-cz,底层由 Commitizen 驱动(config.commitizen.path指向cz-customizable,.cz-config.cjs来自@picgo/bump-version)。同时仓库通过commitlint校验提交信息格式,其规则集直接继承自@picgo/bump-version/commitlint-picgo(package.json#L162-L166),并由husky在prepare阶段注册为 Git 钩子。

实际提交时,按文档执行:

git add . yarn cz

git-cz会以交互式问答引导你选择提交类型(feat / fix / refactor / docs 等)、填写影响范围与描述,最终生成符合 Conventional Commits 规范的提交信息,从而顺利通过 Commitlint 钩子与 CI。这套工具链保证了 PicGo 的 git 历史始终可读、可检索、可自动化生成 changelog(仓库根目录的 CHANGELOG.md 正是基于规范提交维护的)。

七、小结

综上,PicGo 的贡献流程可以浓缩为一条清晰的主线:用 yarn 启动环境 → 按“主进程 / 渲染进程 / 共享层”三目录边界放置代码 → 事件名与全局类型集中注册 → 用 i18n 三步流程扩展多语言 → 清理调试代码后用yarn cz规范提交。其中最关键的心智模型是"渲染进程没有 Node.js 能力",一切需要 Node 模块的操作都必须经由 src/main/events/picgoCoreIPC.ts 中注册的 IPC 事件转发给主进程执行。掌握这些约定后,无论是修复 bug、接入新的图床,还是贡献一门新的语言,你都能在遵守项目架构的前提下快速产出可合并的代码。中文版贡献文档见 CONTRIBUTING.md,更多工程规范(Zustand 状态管理、RPC 路由约定、测试要求等)可进一步阅读 AGENTS.md。

  • 桌面应用
  • 开发工具
  • 插件系统

【免费下载链接】PicGo

:rocket: The Ultimate Image Uploader for Efficient Creators. Supports Obsidian, Typora, VS Code etc. and 60+ image hosting services (S3, GitHub, Cloudflare R2, Imgur, Aliyun OSS...). Paste, upload, done.

项目地址:https://gitcode.com/gh_mirrors/pi/PicGo
点击查看免费下载

相关推荐

上一篇:终极鼠标性能测试指南:3步精准评估您的设备表现
下一篇:魔兽争霸3现代优化指南:让你的经典游戏重焕新生

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

返回列表