Electron 打包后,核心逻辑大多压在 resources/app/dist/electron/main.js 里,而且常常是一整行几十万个字符的压缩代码。当官方版本有 bug、又等不及更新时,直接给它打补丁是最快的救火方式。但单行 JS 动错一个字符就可能让整个应用起不来,这里分享几招踩过坑后总结的安全打法。
为什么是主进程 JS
渲染进程改起来影响小,但真正的发布流程、浏览器自动化、cookie 读写几乎都在主进程。应用升级会把补丁冲掉(官方 asar 覆盖),所以补丁是「临时止血」,不是永久方案------这点要先想清楚。
解包目录优先于 asar
Electron 加载资源时,若存在解包后的 resources/app/ 目录,会优先于 app.asar 生效。所以补丁不用去动 asar,只要把修改后的 main.js 放到解包目录即可,回滚也只需删文件。
用唯一字符串做锚点
单行压缩代码没有行号可言,靠 Edit 工具按行改基本不可能。正确做法是用 str.replace 找一段全局唯一的代码串作为锚点,在它前后插入逻辑。
python
src = open("main.js", encoding="utf-8").read()
anchor = 'console.log("准备确认发布",m),i="确认发布",' # 唯一锚点
assert src.count(anchor) == 1, "锚点不唯一,停止!"
patch = anchor + '\n// >>> 幂等补丁:重复标签不再追加\n'
new = src.replace(anchor, patch)
open("main.js", "w", encoding="utf-8").write(new)
锚点必须 count == 1。如果命中 0 次说明版本变了;命中多次说明选得太泛,可能误改其它逻辑。
用 node --check 兜底语法
改完立刻用 node --check 验证语法,别等启动才发现问题:
bash
node --check main.js
注意 main.js 是单行、体积可能 200KB+,head 看报错会被截断,要用 tail 看尾部才能拿到真正的出错位置。语法错误会让应用直接白屏,这一步省不得。
改前必备份,改后比对
任何补丁前先复制一份带时间戳的备份,出事能秒回滚:
bash
cp main.js main.js.bak-pre0905b
# 改完验证
node --check main.js && echo "语法 OK" || echo "语法坏,回滚"
回滚就是一句 cp main.js.bak-pre0905b main.js。不要相信「我改得很少不会错」。
一个幂等补丁示例
一个真实场景:某段逻辑会无条件往草稿里追加标签,导致重复标签让发布弹窗卡死。改成「先查存在性,不存在才加」即可:
js
for (const t of h) {
const exists = yield e.evaluate((w) => {
const els = document.querySelectorAll(".tag-input .byte-select__tag");
for (const el of els) {
const sp = el.querySelector("span");
if (sp && sp.textContent.trim() === w) return true;
}
return false;
}, t);
if (!exists) yield $t(e, t); // 只在不存在时追加
}
关键改动只有一行:if (!exists) 守住了追加动作。日志里打 TAG_EXISTS / ADD_TAG 就能看出草稿干不干净。
升级会冲掉补丁
应用一升级,resources/app/ 里的手写补丁就会被官方版本覆盖。所以补丁生效期间要记一笔「此处有临时补丁」,升级后重新打。把补丁逻辑本身存成脚本(而不是只改文件),重打就是跑一遍脚本。
回滚与版本管理
补丁不是改完就完事,要有「出问题能瞬间退回」的预案。我的做法是:每次打补丁都生成一份带日期的备份(如 main.js.bak-pre0905b),并把「锚点 + 替换内容」也存进脚本,这样回滚和重打都不依赖记忆。
bash
# 一键回滚到上一个干净版本
cp main.js.bak-pre0905b main.js && node --check main.js && echo "已回滚"
养成「改前备份、改后校验、出问题秒回滚」的肌肉记忆,单行 JS 的雷区就没那么可怕了。
补丁的生命周期管理
给补丁设一个生命周期:临时止血的补丁,在官方修复到达后必须清理,否则会和下一个补丁相互冲突。我习惯在台账里记一笔「补丁位置 + 触发原因 + 预期移除时点」,每次发布前扫一眼,避免补丁堆积成技术债。
热补丁的本质是「在官方修复到达前,用最小、可逆、可验证的改动撑住业务」。唯一字符串锚点 + node 校验 + 时间戳备份,这套组合能让你在单行 JS 的雷区里安全穿行。