从 Electron 12 跳到 25,中间隔着 13 个主版本。这类跨大版本升级,最忌讳一次改完直接跑,因为默认值、废弃 API 和平台支持都在逐个版本变动。下面按“先清理旧调用、再改窗口行为、最后查运行环境”的顺序讲。
一、升级前先处理 remote 模块
很多老项目在渲染进程用 remote 操作主进程能力,但 remote 在 Electron 14 被移除。升级到 25 时,如果代码里还残留 remote,会在启动阶段直接报错。这里给你一个判断依据:
升级前先确认当前主进程和渲染进程是否还在使用Electron 12中已废弃的remote模块。Electron 14移除了remote模块,若代码中仍通过remote.getGlobal或remote.require获取主进程能力,升级到25时应用会在启动阶段直接抛出模块找不到错误。建议先全局搜索 "remote",将相关调用改为ipcRenderer和ipcMain的显式消息传递,再执行版本跳升。
实际操作时,先全局搜索 remote,排除 node_modules 后再看改动量。主进程用 ipcMain.handle 挂接方法,渲染进程用 ipcRenderer.invoke 调用。搜索路径可以这样:
grep -rn "require('electron').remote" src/如果发现调用不多,建议在升级前单独提交一次重构。这样后面版本出问题时,可以用 git bisect 定位是 remote 清理还是其他变更导致的。
二、窗口显示时序要显式控制
从 12 升到 25,最明显的视觉变化是窗口白屏或延迟显示。Electron 15 开始,“show” 和 “ready-to-show” 的默认行为变了,旧代码的窗口绘制时机不再可靠。原话是:
Electron 15将BrowserWindow的"show"和"ready-to-show"事件默认行为调整为不自动显示窗口。从12升级后,如果发现窗口启动时白屏或延迟显示,应检查main进程创建窗口时是否将show设为false且监听ready-to-show后才调用show方法。若沿用旧代码的new BrowserWindow({show: true}),窗口可能因渲染进程未完成绘制而闪现空白,需要改为显式控制window.once('ready-to-show', () => win.show())。
这里有一个兼容写法,可以直接套用:
const win = new BrowserWindow({
show: false,
webPreferences: { preload: path.join(__dirname, 'preload.js') }
})
win.once('ready-to-show', () => win.show())注意,如果你的业务逻辑里有依赖窗口立即显示的副作用,比如在创建后马上截图或量取尺寸,改用 ready-to-show 后这些时机都会延后。需要把这类逻辑挂到窗口的 did-finish-load 事件里去。
三、沙箱默认开启后,渲染进程的 Node 操作要迁移
另一个高频报错是渲染进程出现 “process is not defined” 或 “require is not defined”。这不是环境坏了,而是 Electron 22 起 V8 沙箱默认开启,渲染进程里不再注入 Node 环境。你原来在页面里直接 require('fs')、读 process.env 的写法全部失效。
建议把渲染进程需要的能力挪到 preload 脚本里,通过 contextBridge 暴露成安全接口。例如,页面里要读取一个配置文件,可以这样写:
preload.js:
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('api', {
readConfig: () => ipcRenderer.invoke('read-config')
})主进程里对应注册 handler:
ipcMain.handle('read-config', (event) => readFileSync('config.json', 'utf8'))如果你的代码量很大,短期内迁移不完,临时可以把 BrowserWindow 的 webPreferences 改回 sandbox: false 和 nodeIntegration: true。但这是一条绕开默认安全模型的路,只建议在可控内部工具里用,窗口会暴露给不受信内容时要格外小心。
四、Windows 7 和 Worker 的边界
如果你的目标用户里还有 Windows 7,这一步必须在升级前确认。Electron 23 移除了 Windows 7/8.1 支持,升级后在这些系统上会启动崩溃。原描述是:
注意Electron 23移除了经典的Windows 7/8/8.1支持。如果目标用户群仍有Windows 7设备,升级后应用在Win7上会启动崩溃或无法安装。建议在发布前将package.json中的electron版本锁定到22.x分支,或通过win.setAppUserModelId和process.platform判断系统,对旧系统给出明确提示。同时需检查.nsis安装脚本中是否使用了Win7专属API,避免安装器在旧平台上异常退出。
如果你决定继续支持 Win7,就不要升过 22,版本锁死即可。另外,Electron 25 里 Web Worker 的 Node 集成也默认关闭了,worker 线程里访问 process 或 Buffer 会直接中止。需要把 worker 需要的数据用 postMessage 传进去,或者改成主线程计算。
五、升级前最后的检查清单
- 全局搜索
remote,把 remote 调用全部替换为 IPC,再开始升级。 - 创建窗口时显式设置
show: false,并监听ready-to-show再调用show()。 - 确认所有 BrowserWindow 的 webPreferences 都设了
contextIsolation: true和nodeIntegration: false,迁移渲染进程的 Node 调用到 preload。 - 如果你的安装包针对 Windows 7,锁定 Electron 22.x,不要升到 23+。
- 检查 worker 线程代码,去掉
process、Buffer等 Node 全局对象。 - 把创建窗口的代码包在
app.whenReady().then()里,避免在 ready 之前操作。
以上这些点,每一项都能对应到启动阶段或运行阶段的报错。跨大版本升级时,先处理 remote 和窗口时序,再解决沙箱迁移,最后核对系统兼容。每改完一类,就跑一次主流程,而不是等全部改完一次性验证。如果你的项目里还有原生模块或自定义协议,也需要额外检查,但优先把上面这些默认值差异对齐。