Electron 打包体积偏大时,先要把问题拆开:是安装包(exe/dmg/AppImage)大,还是安装后落盘占用的空间大。这两种情况的处理路径不同。Electron 自带 Chromium 和 Node 运行时,基础体积通常就在一百多 MB 的量级,想压到和原生小工具一样并不现实;真正能优化的是额外的部分:被一起打进去的开发依赖、多平台或多架构的重复产物、没用到的语言包、sourcemap,以及被误打进应用资源的大文件。
判断顺序建议是:先用du和asar list拆开看体积分布,再改 electron-builder 的files/dependencies过滤规则,最后才考虑裁语言包、换压缩级别。如果体积大头是 Chromium 本体,优化空间有限,重点应放在多架构合并、差分更新和资源清理上;任何裁剪都要在启动冒烟测试通过后再固定下来,且不要在未确认业务是否需要多语言、原生模块的情况下删除。
先确认当前场景和目标
先确认三类信息,再动手改配置。第一,看体积是出在安装包还是安装后的目录。安装包有压缩,安装后目录是解压结果,两者差几十 MB 很正常,不要拿安装包大小去对照安装后目录里的文件。第二,确认要出几个平台、几个架构。同时出 x64 和 arm64,或者用 universal 包,体积会明显上去。第三,确认 node_modules 是不是被整包带进去了:Electron 项目常见的情况是 dependencies 里混着构建工具、测试框架这类只在开发期用的包。
可以先跑几条检查命令,把体积分布摸清楚:
# 看产物目录里谁占空间
du -sh dist/* | sort -h
# 看 asar 里排在前面的文件
npx asar list dist/mac/YourApp.app/Contents/Resources/app.asar | head -50
# 看 dependencies 里是否混入了开发期依赖
npm ls --omit=dev --depth=0
目标也要定得现实一点:如果业务只需要一个平台、一个架构,把未使用平台产物和多余语言包去掉,体积通常会回到一个比较合理的水位;如果产品必须同时支持 Windows、macOS 和 Linux,还要求 x64 与 arm64,那体积上限就由这些约束决定,优化的目标应是“去掉不该有的”,而不是“强行压到某个数字”。
按这个顺序处理
处理顺序建议从影响大、风险低的地方开始,逐步向风险高的裁剪推进。

- 先分清
dependencies与devDependencies。把只在打包、构建、测试阶段用的包移到devDependencies,主进程运行时真正require的包才留在dependencies。打包机的安装步骤建议用npm ci --omit=dev之类的命令,避免开发依赖进入产物。 - 用
files白名单收窄打包范围。files支持 glob,推荐写“要什么”而不是“排除什么”,这样新增的临时文件不会意外被打进去:
# electron-builder.yml 片段
files:
- "main/**/*"
- "renderer/dist/**/*"
- "package.json"
- "!**/*.map"
- "!**/{test,__tests__,docs,example,examples}/**"
- "!**/.git/**"
asar: true
compression: maximum
# 只出需要的架构,避免 universal 包体积叠加
mac:
target:
- target: dmg
arch: [arm64]
3. 检查 asarUnpack。原生 .node 文件、需要以真实路径访问的资源必须解包,但不要把整个目录解包,否则 asar 的压缩收益就没了。
4. 裁掉不需要的 Chromium 语言包。产物里的 locales 目录通常包含几十种 .pak 文件,只保留业务实际使用的语言能省下一部分。做法是在 electron-builder 的 afterPack 钩子里删除多余文件,删除前要确认拼写检查、右键菜单等依赖语言包的功能不受影响。
5. 清理静态资源。图标、字体、示例视频、日志文件这类资源经常被顺手打进 extraResources,用 du 对着资源目录过一遍,确认哪些是运行时真的需要的。
6. 最后再考虑拆包。如果渲染层依赖很重,把主进程和渲染进程分开构建、渲染层用构建产物而不是源码目录,可以减少被打进主进程包的内容。
改完后怎么验证
改完配置后,不要只看构建有没有报错,要按下面几步确认体积和功能都还在预期内。
- 重新构建后对比
du -sh dist与之前记录的数字,同时记录安装包大小和安装后目录大小,分开比较。 - 用
npx asar list确认被排除的目录确实不在包里,重点看node_modules下是否还有构建工具残留。 - 在干净机器或干净用户目录下安装并启动,走一遍主流程:打开窗口、加载本地资源、读写文件、调用原生模块、检查更新。体积优化最容易出问题的就是动态拼路径
require和解包资源读取。 - 如果裁了语言包,切换系统语言或打开右键菜单、拼写检查,确认没有缺文件报错。
- 确认签名与公证流程仍能通过,尤其是 macOS 上改动
Resources目录内容之后。
符合预期的信号是:安装包与安装后目录都变小,应用启动正常,控制台没有 Cannot find module 或资源 404 类错误,更新流程能正常下载并安装新版本。
容易忽略的边界
有几类限制需要提前想清楚,否则容易在优化后踩坑。第一,compression: maximum 会增加构建时间,CI 上打包时长可能明显上升,是否值得要结合发布频率判断。第二,asar 对通过字符串拼接路径读取文件的代码不友好,这类代码要么改成 path.join 配合 app.getAppPath(),要么把文件放进 asarUnpack。第三,原生模块和依赖特定平台二进制的包不能随意裁剪,跨平台构建时尤其要确认每个目标平台都有对应产物。第四,删语言包、删资源属于“按当前业务假设裁剪”,如果产品后续要支持多语言或多地区,需要保留回退方案,比如在构建配置里用变量控制保留的语言列表,而不是硬编码删除。第五,如果体积问题主要来自 Chromium 本体,继续在业务代码上做裁剪的收益有限,此时更现实的方向是减少发布平台与架构数量、使用增量更新,或评估是否真的需要桌面端全量安装包。