Mac 下手动安装 PicGo Gitee 上传插件解决方案

Mac 下手动安装 PicGo Gitee 上传插件解决方案

适用场景 :PicGo GUI 插件市场无法下载插件、npm install 超时或网络异常,需要手动离线安装 picgo-plugin-gitee-uploader 的 Mac 用户。


背景

PicGo 是一款优秀的图床管理工具,picgo-plugin-gitee-uploader 插件可以让你把图片上传到 Gitee(码云)仓库。

然而在国内网络环境下,通过 PicGo GUI 的插件市场或者 npm install 安装该插件时,经常遇到以下问题:

  • GUI 界面点击安装无响应或报错
  • npm install picgo-plugin-gitee-uploader 超时
  • 即使安装成功,插件也不出现在图床列表中

本文提供一套完整的离线手动安装方案,无需依赖网络即可完成安装。


原理说明

PicGo 插件本质上是一个 Node.js 模块,放在以下目录:

复制代码
~/Library/Application Support/picgo/node_modules/

PicGo 通过读取同目录下的 data.json 文件中的 picgoPlugins 字段来识别已安装的插件。

该插件源码是 TypeScript,需要编译为 CommonJS 格式的 JavaScript 才能被 Node.js 加载。


前置准备

  1. 已安装 PicGo Mac 客户端
  2. 已安装 Node.js(推荐 v16+),可通过 node --version 验证
  3. 已下载 picgo-plugin-gitee-uploader 源码包并解压到 ~/Downloads/picgo-plugin-gitee-uploader-master

步骤一:确认目录结构

确保以下两个目录存在:

bash 复制代码
# PicGo 数据目录
~/Library/Application\ Support/picgo/

# 插件源码目录
~/Downloads/picgo-plugin-gitee-uploader-master/

确认插件源码目录包含以下文件:

复制代码
picgo-plugin-gitee-uploader-master/
├── index.ts
├── lib/
│   ├── helper.ts
│   ├── interface.ts
│   └── octokit.ts
├── package.json
└── tsconfig.json

步骤二:创建编译输出目录

插件的 package.json"main": "dist/index.js",说明需要编译后的产物。

bash 复制代码
mkdir -p ~/Downloads/picgo-plugin-gitee-uploader-master/dist/lib

步骤三:手动创建编译产物

由于网络问题无法安装 TypeScript 编译器,我们直接手写编译后的 JS 文件。

3.1 创建 dist/lib/interface.js

bash 复制代码
cat > ~/Downloads/picgo-plugin-gitee-uploader-master/dist/lib/interface.js << 'EOF'
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
EOF

3.2 创建 dist/lib/helper.js

新建文件 ~/Downloads/picgo-plugin-gitee-uploader-master/dist/lib/helper.js,内容如下:

javascript 复制代码
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getPath = exports.pathJoin = exports.unzip = exports.zip = exports.getNow = void 0;
const dayjs_1 = require("dayjs");
const normalize_path_1 = require("normalize-path");
const path_1 = require("path");

function getNow() {
    return dayjs_1.default().format('YYYY-MM-DD hh:mm:ss');
}
exports.getNow = getNow;

function zip(img) {
    return { f: img.fileName, s: img.sha };
}
exports.zip = zip;

function unzip(img) {
    const { f: fileName, s } = img;
    const extname = fileName.split('.').slice(-1)[0];
    return { fileName, id: s, sha: s, extname, imgUrl: '', type: '' };
}
exports.unzip = unzip;

function pathJoin(...arg) {
    return normalize_path_1.default(path_1.join.apply(null, arg));
}
exports.pathJoin = pathJoin;

function getPath(path, customPath) {
    if (customPath === '') return path;
    let date = new Date();
    let year = date.getFullYear();
    let month = (date.getMonth() + 1) < 10 ? '0' + (date.getMonth() + 1) : (date.getMonth() + 1);
    if (customPath === 'year') return path.replace('$customPath', year + '');
    if (customPath === 'yearQuarter') {
        let quarter = 'spring';
        if (month >= 4 && month <= 6) quarter = 'summer';
        else if (month >= 7 && month <= 9) quarter = 'autumn';
        else if (month >= 10 && month <= 12) quarter = 'winter';
        return path.replace('$customPath', year + '/' + quarter);
    }
    if (customPath === 'yearMonth') return path.replace('$customPath', year + '/' + month);
    return path;
}
exports.getPath = getPath;

3.3 创建 dist/lib/octokit.js

新建文件 ~/Downloads/picgo-plugin-gitee-uploader-master/dist/lib/octokit.js,完整内容参考本文附录 A,或直接从本仓库复制。

核心逻辑:将 Octo 类从 TypeScript 转为 ES2017 CommonJS,移除所有类型注解。

3.4 创建 dist/index.js

新建文件 ~/Downloads/picgo-plugin-gitee-uploader-master/dist/index.js,完整内容参考本文附录 B。

核心逻辑:将 export = 改为 module.exports =,import 改为 require。


步骤四:手动安装运行时依赖

该插件依赖三个 npm 包:dayjsnormalize-pathurl-join

由于网络问题无法通过 npm 安装,我们在插件目录下手动创建这三个包的最小实现。

bash 复制代码
mkdir -p ~/Downloads/picgo-plugin-gitee-uploader-master/node_modules/dayjs
mkdir -p ~/Downloads/picgo-plugin-gitee-uploader-master/node_modules/normalize-path
mkdir -p ~/Downloads/picgo-plugin-gitee-uploader-master/node_modules/url-join

dayjs shim

新建 node_modules/dayjs/index.js

javascript 复制代码
"use strict";
function dayjs(date) {
  const d = date ? new Date(date) : new Date();
  return {
    format(fmt) {
      const y = d.getFullYear();
      const M = String(d.getMonth() + 1).padStart(2, '0');
      const D = String(d.getDate()).padStart(2, '0');
      const h = String(d.getHours()).padStart(2, '0');
      const m = String(d.getMinutes()).padStart(2, '0');
      const s = String(d.getSeconds()).padStart(2, '0');
      return fmt
        .replace('YYYY', y).replace('MM', M).replace('DD', D)
        .replace('hh', h).replace('mm', m).replace('ss', s);
    }
  };
}
module.exports = dayjs;
module.exports.default = dayjs;

新建 node_modules/dayjs/package.json

json 复制代码
{"name":"dayjs","version":"1.11.0","main":"index.js"}

normalize-path shim

新建 node_modules/normalize-path/index.js

javascript 复制代码
"use strict";
module.exports = function normalizePath(path, stripTrailing) {
  if (typeof path !== 'string') throw new TypeError('expected a string');
  path = path.replace(/[\/\\]+/g, '/');
  if (stripTrailing !== false) path = path.replace(/\/$/, '');
  return path;
};

新建 node_modules/normalize-path/package.json

json 复制代码
{"name":"normalize-path","version":"3.0.0","main":"index.js"}

url-join shim

新建 node_modules/url-join/index.js

javascript 复制代码
"use strict";
function normalize(str) {
  return str.replace(/([^:])(\/+)/g, '$1/');
}
function urlJoin() {
  const parts = Array.from(arguments).reduce((acc, val) => {
    if (Array.isArray(val)) return acc.concat(val);
    acc.push(val); return acc;
  }, []);
  let joined = parts.map((part, i) => {
    if (i === 0) return part.replace(/\/*$/, '');
    return part.replace(/^\/*(.+?)\/*$/, '$1');
  }).join('/');
  return normalize(joined);
}
module.exports = urlJoin;
module.exports.default = urlJoin;

新建 node_modules/url-join/package.json

json 复制代码
{"name":"url-join","version":"4.0.1","main":"index.js"}

步骤五:验证插件是否可加载

bash 复制代码
node -e "const p = require('$HOME/Library/Application Support/picgo/node_modules/picgo-plugin-gitee-uploader'); console.log(typeof p, 'loaded OK');"

输出 function loaded OK 说明插件加载成功。


步骤六:确认符号链接

PicGo 会在 node_modules 下创建指向插件目录的符号链接,检查是否存在:

bash 复制代码
ls -la ~/Library/Application\ Support/picgo/node_modules/

应看到类似:

复制代码
lrwxr-xr-x  picgo-plugin-gitee-uploader -> ../../../../Downloads/picgo-plugin-gitee-uploader-master

如果没有,手动创建:

bash 复制代码
ln -s ~/Downloads/picgo-plugin-gitee-uploader-master \
  ~/Library/Application\ Support/picgo/node_modules/picgo-plugin-gitee-uploader

步骤七:注册插件到 data.json

用文本编辑器(或直接在终端)修改 ~/Library/Application Support/picgo/data.json,找到 picgoPlugins 字段:

json 复制代码
"picgoPlugins": {}

改为:

json 复制代码
"picgoPlugins": {"picgo-plugin-gitee-uploader": true}

⚠️ 修改前先备份:cp ~/Library/Application\ Support/picgo/data.json ~/Desktop/data.json.bak


步骤八:重启 PicGo 并配置

  1. 完全退出 PicGo(菜单栏右键 → 退出)
  2. 重新启动 PicGo
  3. 进入 图床设置 → 左侧列表应出现 gitee 选项
  4. 填写配置:
字段 说明 示例
repo 仓库路径(用户名/仓库名) yourname/picBed
branch 分支名 master
token Gitee 私人访问令牌 在 Gitee 设置 → 私人令牌 获取
path 图片存储子目录(可选) imgs/
customUrl 自定义图片访问域名(可选) 留空则使用 gitee.com
  1. 点击 确定 并设为默认图床
  2. 测试上传图片 ✓

常见问题

Q: PicGo 重启后插件还是不显示?

A: 检查 data.json 是否保存成功,确认 picgoPlugins 字段值为 {"picgo-plugin-gitee-uploader": true} 而非 {}

Q: 上传时报 Error in repo name

A: repo 字段必须是 用户名/仓库名 格式,例如 zhangsan/myPicBed,不能只写仓库名。

Q: 上传时报 401/403 错误?

A: Gitee token 失效或权限不足。在 Gitee → 设置 → 私人令牌 中重新生成,勾选 projects 权限。

Q: 为什么不直接用 npm install 安装?

A: 国内网络访问 npm 官方源极慢,经常超时。本文方案完全离线,不依赖网络,更稳定可靠。如果你的网络正常,也可以直接运行:

bash 复制代码
cd ~/Library/Application\ Support/picgo
npm install picgo-plugin-gitee-uploader --save

总结

整个手动安装流程分为三个核心步骤:

  1. 编译 :将 TypeScript 源码手动转为 CommonJS JS,生成 dist/ 目录
  2. 依赖 :为三个运行时依赖(dayjsnormalize-pathurl-join)创建最小实现
  3. 注册 :在 data.jsonpicgoPlugins 中将插件标记为 true

这套方法同样适用于其他 PicGo 插件的离线手动安装,举一反三即可。


参考链接


本文操作环境:macOS Sequoia 15、Node.js v16.20.2、PicGo 2.x

相关推荐
是翔仔呐3 小时前
第2章 按键输入与消抖!掌握I/O口输入核心,实现单片机人机交互
c语言·单片机·嵌入式硬件·gitee
feasibility.3 小时前
Mac终端的tmux会话使用Codex 时Ctrl+V 可能触发异常并导致会话假死问题以及解决方法
linux·运维·macos·tmux·codex
zhensherlock3 小时前
Protocol Launcher 系列:Pika 取色器的协议控制(上篇)
前端·javascript·macos·typescript·github·mac·view design
__WanG18 小时前
Mac 本地部署 OMLX + 通义千问 Qwen3.5-27B 保姆级教程
macos
节点小宝19 小时前
一站式部署:支持Windows、macOS、Linux三端的统一方案
linux·运维·macos
呆萌小新@渊洁21 小时前
音频识别入门内容
macos·音视频·xcode
觉醒程序员1 天前
Mac电脑硬盘扩容后,如何重装git,node更干净
macos
ShineWinsu1 天前
对于Linux:git版本控制器和cgdb调试器的解析
linux·c语言·git·gitee·github·调试·cgdb
是翔仔呐1 天前
第6章 UART串口通信!掌握单片机与外界的双向数据通道,实现跨设备交互
c语言·开发语言·单片机·嵌入式硬件·gitee