Electron 如何持久化数据?
· 5 min read
Electron 持久化没有"标准答案",按数据类型选方案,比选库更重要。
- 写对目录:一律写
app.getPath('userData'),打包后应用目录是只读的。 - 配置 / 偏好:用
electron-store,一个 JSON 文件搞定,不用自己fs。 - 结构化大数据:上
better-sqlite3,同步 API,比 IndexedDB 省心。 - 敏感信息:token / 密码走
safeStorage,落盘前用系统钥匙串加密。 - 别踩的坑:renderer 里的
localStorage会被用户清缓存清掉,不能当数据库。
先想清楚:数据写到哪里
Electron 持久化第一件事不是选库,是选目录。 大部分人第一次做持久化都栽在这——把文件写进应用自己的目录,开发时一切正常,打包成 .app / .exe 后直接报权限错误。
打包后的应用资源目录(app.asar 所在的地方)是只读的,而且升级会被整包覆盖。用户数据必须写到系统给每个应用分配的可写目录:
const { app } = require('electron');
// 这才是该写数据的地方
app.getPath('userData');
// macOS: ~/Library/Application Support/<AppName>
// Windows: %APPDATA%\<AppName>
// Linux: ~/.config/<AppName>
app.getPath() 还有 temp、logs、downloads 等 key。规律很简单:要留下来的东西写 userData,临时的写 temp。
五种方案,按数据类型选
| 数据类型 | 推荐方案 | 进程 | 说明 |
|---|---|---|---|
| 配置 / 用户偏好 | electron-store | 主进程 | 键值对,JSON 落盘 |
| 结构化 / 大数据 | better-sqlite3 | 主进程 | 关系型,同步查询 |
| 敏感凭据 | safeStorage | 主进程 | 系统钥匙串加密 |
| 页面临时状态 | IndexedDB | 渲染进程 | 随窗口,可被清缓存 |
| 二进制文件 | fs + userData | 主进程 | 图片、缓存、导出文件 |
核心判断:能放主进程就别放渲染进程。 渲染进程的 Web 存储(localStorage / IndexedDB)虽然写起来最顺手,但它绑定在 Chromium 的用户数据里,用户清缓存、你切换窗口分区(partition)都可能丢,天生不适合当"真正的数据库"。