资讯动态

解决electron-builder卡在fpm下载:配置镜像加速打包

发布时间:2026/9/9 20:45:28 来源:尧图企业网站定制
最近在折腾 Electron 应用打包的时候我遇到了一个特别烦躁的问题项目在本地 Windows 上打包 Windows 安装包一切正常但一到 Linux 环境打 deb 包electron-builder 就卡在下载 fpm 这一步要么超时要么几百 KB 的速度最后直接构建失败。当时的报错大概是Cannot download fpm-2.9.3-2.7z: ...这种一看就知道是默认的 GitHub Releases 下载地址访问不稳定。折腾下来核心解决办法就是给 electron-builder 自定义 fpm 镜像地址。这篇文章我会把整个方案讲透包括 electron-builder 打包 Linux 各种包时 fpm 到底干什么、默认从哪里下载、怎么通过环境变量换成镜像地址、以及离线环境和 CI 流水线里最省心的配置方式。内容偏实战适合正在用 electron-builder 出 deb/rpm 包、并且在网络环境不那么顺畅时被 fpm 下载坑过的朋友参考。1. 先搞清楚electron-builder 打包时 fpm 到底扮演什么角色很多人第一次看到 fpm 是在打包日志的Downloading fpm那一行然后就开始到处搜怎么解决。其实先理解 fpm 是什么、为什么 electron-builder 要调用它后面配镜像的时候心里就踏实多了。1.1 fpm 是什么为什么 electron-builder 会盯上它fpm 的全称是effing package management是一个基于 Ruby 的命令行工具专门用来把任意目录、文件转换成各种 Linux 安装包格式比如 deb、rpm、pacman、apk 等等。electron-builder 在打包 Linux 目标时本质上是先把 Electron 应用的可执行文件、资源文件、依赖库整理到一个临时目录然后把这个目录交给 fpm 去打成 deb 或 rpm 安装包。fpm 负责处理安装包里的目录结构、依赖声明、postinst/prerm这类维护脚本以及在 Ubuntu 系里很重要的 desktop 文件集成。具体到安装包属性比如 deb 包的维护者邮箱maintainer、包名packageName、依赖库声明depends、安装后执行的脚本这些 electron-builder 本身有配置项但真正写进 deb 包头部信息的是 fpm。所以在旧版 electron-builder22.x 及更早里fpm 是一个绕不开的外部依赖。到了 24.x 之后electron-builder 把 deb 打包逻辑用 Go 重写了内置在app-builder二进制里不再强制拉 fpm但很多项目还在用 22.x / 23.x或者需要打 rpm 包fpm 依然是刚需。1.2 fpm 从哪来预编译二进制拉取逻辑electron-builder 并不要求你在系统里用gem install fpm装 fpm它更倾向于直接下载一个别人预编译好的 fpm 可执行文件。这个预编译版本放在 electron-builder 官方组织维护的electron-builder-binaries仓库的 GitHub Releases 页面里文件名类似fpm-2.9.3-2.7z。下载逻辑在 electron-builder 的源码里写得很直接构造一个下载 URL默认前缀是https://github.com/electron-userland/electron-builder-binaries/releases/download然后拼上具体的版本目录和文件名下载后用内置工具解压到缓存目录。这个缓存目录在 Linux 上是~/.cache/electron-builder在 macOS 上是~/Library/Caches/electron-builder在 Windows 上是%LOCALAPPDATA%\electron-builder\Cache。问题就出在这个默认下载前缀上。GitHub Releases 在很多网络环境里并不稳定下载 fpm 这种几十 MB 的压缩包很容易断流。electron-builder 源码里留了后门下载器会检查环境变量ELECTRON_BUILDER_BINARIES_MIRROR一旦设置了就用这个值替换默认前缀。这就是自定义 fpm 镜像地址最核心的入口。2. 镜像地址怎么配环境变量、配置文件、缓存的完整打法理解了下载流程配置就顺理成章了。自定义 fpm 镜像地址主要有三种打法设置全局环境变量、在项目配置文件里固话、以及手动下载 fpm 配合离线缓存。实际生产里我会混合使用尤其是 CI 环境。2.1 主角ELECTRON_BUILDER_BINARIES_MIRROR 环境变量ELECTRON_BUILDER_BINARIES_MIRROR这个环境变量名看起来很长但它管的是 electron-builder 从electron-userland/electron-builder-binaries拉取的所有二进制不止 fpm还包括 winCodeSign、nsis、nsis-resources 等。一旦设置了它electron-builder 下载这些工具时都会走镜像地址。最常见的配置是把它指向 npmmirror 提供的 electron-builder-binaries 镜像。在 Linux 终端里执行export ELECTRON_BUILDER_BINARIES_MIRRORhttps://npmmirror.com/mirrors/electron-builder-binaries/Windows PowerShell 里的写法$env:ELECTRON_BUILDER_BINARIES_MIRRORhttps://npmmirror.com/mirrors/electron-builder-binaries/设置之后再跑打包命令日志里就会发现下载 fpm 的地址变成了https://npmmirror.com/mirrors/electron-builder-binaries/fpm-2.9.3-2/fpm-2.9.3-2.7z速度通常会有质的提升。这里有几个细节需要注意。镜像地址末尾的斜杠最好带上以免拼接 URL 时出现双斜杠或者缺斜杠的问题。这个环境变量只对从 GitHub Releases 下载的那一批二进制生效并不能影响 Electron 主程序本身的二进制下载那是另一个环境变量ELECTRON_MIRROR管的。2.2 顺带解决 Electron 安装包的镜像问题既然说到镜像我建议把配套的都一起配了。Electron 应用在打包时还会下载 Electron 官方预编译二进制也就是electron-v31.0.0-linux-x64.zip这类文件这个下载走的是ELECTRON_MIRROR环境变量。如果这个也不稳定打包还是会在别的环节卡住。常用的配套配置export ELECTRON_MIRRORhttps://npmmirror.com/mirrors/electron/在 npm 项目里还可以通过.npmrc文件固化这个设置electron_mirrorhttps://npmmirror.com/mirrors/electron/ electron_builder_binaries_mirrorhttps://npmmirror.com/mirrors/electron-builder-binaries/注意.npmrc里这两种配置是很多 Electron 开发者实际验证过的写法npm 在安装electron包时它的 postinstall 脚本会读取这些配置来决定去哪里下载二进制所以具备跨平台的持久化能力。2.3 配置 electron-builder.yml 里的 fpm 参数有朋友会把自定义 fpm 镜像地址理解成在electron-builder.yml里加一个fpm字段然后把镜像地址写进去。这其实是一个误区。linux.fpm配置项是用来往 fpm 命令里传额外参数的比如linux: target: - deb - rpm fpm: --deb-no-default-config-files: true它改变的是 fpm 生成安装包的行为不能改变 fpm 本身的下载地址。镜像地址必须通过环境变量或.npmrc来指定。这一点很容易搞混我在网上看到不少人把镜像地址塞到 fpm 字段里结果打包直接报参数错误白折腾半天。如果你需要给 deb 包加自定义依赖、修改包描述、设置优先级这些才是fpm字段的用武之地。合理使用这个配置项可以让你少封装一层脚本比如linux: executableName: my-app fpm: --depends: libgtk-3-0 --deb-priority: optional这样打出来的 deb 包会在包管理器的依赖信息里体现libgtk-3-0安装时 apt 会自动拉取。3. 实操记录一行命令改镜像打包终于不卡了理论讲完下面是我的完整实操过程。我这边复现环境是 Ubuntu 22.04Node.js 18electron-builder 22.14.13目标是打一个 deb 包。如果你用的是 24.x 版本流程基本一致只是日志里的下载行可能会少一些。3.1 第一步确认本地环境和当前缓存状态动手前先看一眼当前 electron-builder 版本和缓存目录里有没有 fpm 的残留。我在项目根目录执行npx electron-builder --version然后检查缓存目录ls -la ~/.cache/electron-builder如果之前下载失败过这里通常会有fpm-2.9.3-2目录或者.7z.part之类的临时文件。建议先清空 fpm 相关目录避免后面打包时用了不完整的缓存rm -rf ~/.cache/electron-builder/fpm-2.9.3-23.2 第二步验证镜像地址是否真的可用在设置环境变量之前我习惯先用 curl 测试一下镜像地址能不能访问。不要小看这一步有时候镜像本身没问题但 URL 路径拼错了下载 404 还会报错。直接测试curl -I https://npmmirror.com/mirrors/electron-builder-binaries/fpm-2.9.3-2/fpm-2.9.3-2.7z如果返回 200说明路径正确。如果返回 404可以到https://npmmirror.com/mirrors/electron-builder-binaries/首页去翻一下实际的目录名看看你需要的 fpm 版本目录叫什么。有的版本号不同直接用默认的版本号去访问不一定会命中。这里提一个实际经验electron-builder 22.x 默认拉的是fpm-2.9.3-2但不同小版本可能有一点差异。与其靠猜不如先让 electron-builder 跑一次从失败日志里把完整下载 URL 复制出来再把https://github.com/electron-userland/electron-builder-binaries/releases/download部分替换成镜像地址 curl 一下绝对可靠。3.3 第三步设置环境变量并打包确认镜像通到之后直接在同一个终端里设置环境变量再跑打包export ELECTRON_BUILDER_BINARIES_MIRRORhttps://npmmirror.com/mirrors/electron-builder-binaries/ export ELECTRON_MIRRORhttps://npmmirror.com/mirrors/electron/ npx electron-builder --linux deb日志里如果出现类似下面的行说明 fpm 已经在走镜像了• downloading urlhttps://npmmirror.com/mirrors/electron-builder-binaries/fpm-2.9.3-2/fpm-2.9.3-2.7z第一次打包要解压 fpm会多花点时间之后的构建就会用缓存不会再下载。整个流程走通后dist目录下会生成my-app_1.0.0_amd64.deb。如果你用的是 yarn打包命令可以写成yarn electron-builder --linux deb环境变量的设置方式不变yarn 会原样继承当前 shell 的环境变量。3.4 第四步CI 流水线里固化配置在 GitHub Actions 里环境变量可以写在工作流的 env 字段中env: ELECTRON_BUILDER_BINARIES_MIRROR: https://npmmirror.com/mirrors/electron-builder-binaries/ ELECTRON_MIRROR: https://npmmirror.com/mirrors/electron/在 GitLab CI 里可以在变量设置页面添加也可以在.gitlab-ci.yml的变量区配置variables: ELECTRON_BUILDER_BINARIES_MIRROR: https://npmmirror.com/mirrors/electron-builder-binaries/ ELECTRON_MIRROR: https://npmmirror.com/mirrors/electron/如果你用的是 Docker 镜像作为构建环境记得在 Dockerfile 里用 ENV 指令固化ENV ELECTRON_BUILDER_BINARIES_MIRRORhttps://npmmirror.com/mirrors/electron-builder-binaries/ ENV ELECTRON_MIRRORhttps://npmmirror.com/mirrors/electron/这条我实际踩过坑一开始我把环境变量写在 CI 的 shell 命令行里比如ELECTRON_BUILDER_BINARIES_MIRRORxxx npm run build但 Docker 镜像里的某些缓存步骤可能不重新执行导致看起来环境变量生效了实际下载还是走了旧地址。后来直接在 Dockerfile 里 ENV 固化一劳永逸。还有个技巧CI 里能开缓存就开缓存。GitHub Actions 可以缓存~/.cache/electron-builder这样后续的流水线不会每次重新下载 fpm- name: Cache electron-builder uses: actions/cachev3 with: path: ~/.cache/electron-builder key: electron-builder-${{ runner.os }}-${{ hashFiles(**/package-lock.json) }}这一步对提速效果非常明显尤其适合频繁跑多平台打包的团队。4. 踩坑实录镜像配置里那些容易翻车的地方镜像地址配置本身不难但在实际项目里会撞上各种奇奇怪怪的状况。我整理了这两年积累的问题排查经验每一条都是真实出现过的。4.1 下载 fpm 一直超时但换镜像后还是超时这种情况我把镜像地址从 npmmirror 换成另一个云的源发现依然超时。后来排查发现electron-builder 22.x 在某些环境下会先解析 GitHub 的releases接口获取最新版本信息而这个接口本身就不稳定。深入看日志发现超时发生在Downloading之前的Check阶段。解决办法其实不复杂保证系统能稳定访问你指定的镜像即可检查镜像的域名解析是否正常可以 ping 一下镜像域名或者用curl -I测响应头。很多时候超时不是 electron-builder 的锅而是镜像源本身对你所在的网络链路就慢。4.2 镜像路径 404最常见的翻车点镜像地址不是随便填https://mirror.example.com就完事它必须加上electron-builder-binaries这个路径前缀。我见过有人只填到域名根路径下载 URL 变成https://npmmirror.com/fpm-2.9.3-2/fpm-2.9.3-2.7z当然是 404。检查方法就是我在实操里写的先 curl 完整 URL确认返回 200 再打包。如果你使用的 electron-builder 版本对应的 fpm 版本很新镜像站点还没同步也会 404。这种情况下可以换一个包含该版本的镜像源或者手动将 fpm 压缩包放到缓存目录。4.3 完全离线环境手动放置 fpm 到缓存目录有些服务器根本没有外网所有包都要通过内部仓库投递。这种场景下环境变量已经救不了了因为镜像也访问不到。最稳妥的做法是在有网的机器上把 fpm 压缩包下载好然后手动放进构建机的缓存目录。具体步骤是# 在有网环境下载 curl -L https://npmmirror.com/mirrors/electron-builder-binaries/fpm-2.9.3-2/fpm-2.9.3-2.7z -o fpm-2.9.3-2.7z # 传到离线构建机放到对应缓存目录 mkdir -p ~/.cache/electron-builder/fpm-2.9.3-2 mv fpm-2.9.3-2.7z ~/.cache/electron-builder/fpm-2.9.3-2/fpm-2.9.3-2.7zelectron-builder 检测到缓存目录里已经有完整文件就不会再走下载流程。注意文件名必须完全一致否则它会再次尝试下载。这个方案对 npm 内网私服的组合也很常用先npm pack获取所有依赖再手动补充 fpm 压缩包。还有个更偏门的方式直接改用系统 fpm。在环境变量里设置USE_SYSTEM_FPMtrueelectron-builder 会跳过内置 fpm改用系统里gem install fpm装好的版本。这个方案适合对 fpm 版本有强诉求的场景但需要额外处理 Ruby 环境而且是官方文档里明确说明的“实验性”用法不建议作为首选。4.4 缓存不生效明明用了镜像还是反复下载如果你确认镜像没问题、文件也下载成功了但每次打包还在疯狂下载多半是缓存目录权限或磁盘空间的问题。electron-builder 在解压 fpm 时需要临时空间如果~/.cache所在分区快满了解压会静默失败或者只解压一部分下次构建又当成没有缓存处理。还有一种情况是 CI 里缓存路径配错了。比如 GitHub Actions 的hashFiles(**/package-lock.json)这个 key 里如果你第一次构建时镜像没生效、下载失败缓存会把“失败状态”也存下来但更多时候是缓存 key 频繁变化导致缓存命中率低。我建议可以在缓存 key 里固定一个外层版本号避免每次package-lock.json一改动就全部失效。4.5 常见问题速查表症状常见原因解决方案downloading url...fpm...长时间无进展默认 GitHub Releases 下载不稳定设置ELECTRON_BUILDER_BINARIES_MIRROR镜像地址返回 404路径漏了electron-builder-binaries子路径用 curl 验证完整下载 URL打包时报 fpm 解压失败缓存文件损坏清理~/.cache/electron-builder下 fpm 目录项目是 electron-builder 24还是报 fpm 相关打的 rpm/apk 包仍需要外部 fpm同样配置环境变量或升级到最新版本CI 每次全量下载 fpm缓存未配置或 key 变动频繁配置流水线缓存并固化 key离线环境无法下载任何文件构建网络受限手动放置 fpm 7z 到缓存目录这张表基本覆盖了我遇过的问题。如果你正卡着 fpm 下载建议优先看第一行和第三行大部分情况不是环境变量没配就是缓存坏了。最后再分享一个小技巧排查这类下载问题时一定把 electron-builder 的日志级别调到 debug打包命令加--debug参数或者设置环境变量DEBUGelectron-builder*日志里会打印出完整的请求 URL 和解压路径。这样不管换成哪个镜像你都能在几秒内判断出问题出在下载环节还是解压环节不用对着失败日志瞎猜。实际用下来这个调试方式帮我省掉的时间比设置镜像本身还多。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价