关于 electron-dev
面向使用 Electron Vite 和 Electron Builder 开发应用的技能,涵盖架构、安全、IPC、配置与验证实践。
主要功能
- 01主进程、渲染进程与预加载脚本职责
- 02进程间安全隔离
- 03IPC 通道白名单与参数验证
- 04electron-vite 配置指导
- 05原生模块构建指导
- 06类型检查与测试清单
适用场景
- 01规划 Electron 应用架构
- 02保护渲染进程与主进程通信
- 03配置原生模块构建
- 04完成前检查 Electron 变更
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ pedronauck/ skills --skill electron-dev安装后在 Claude Code 中输入/electron-dev确认已加载。
附带文件references/patterns.md
详细介绍
Electron 开发指南
本技能为使用 Electron Vite 和 Electron Builder 构建可用于生产环境的 Electron 应用提供指南、模式和最佳实践。
快速开始
- 核心规则:有关 Electron 开发模式和指南的详细信息,请参阅此技能中的
references/patterns.md。 - 安全性:始终启用
contextIsolation和sandbox,并禁用nodeIntegration。 - 架构:主进程负责处理 Node.js 操作;渲染进程专注于 UI;预加载脚本负责在两者之间建立安全桥梁。
进程架构
主进程(Node.js 上下文)
主进程负责处理:
- 窗口创建和生命周期
- 文件系统和数据库操作
- IPC 消息处理
- 应用级事件
关键指南:
- 创建窗口前使用
app.isReady() - 在
window.destroyed事件中清理资源 - 使用
app.on('before-quit')处理优雅关闭
渲染进程(前端上下文)
渲染进程:
- 使用 Web 技术(React、Vue 等)渲染 UI
- 仅通过 IPC 与主进程通信
- 绝不能直接访问 Node.js API
预加载脚本(安全层)
预加载脚本是渲染进程与主进程之间的唯一桥梁:
import { contextBridge, ipcRenderer } from "electron";
contextBridge.exposeInMainWorld("electronAPI", {
invoke: (channel: string, args?: unknown) => {
const validChannels = ["db:query", "file:save", "app:close"];
if (validChannels.includes(channel)) {
return ipcRenderer.invoke(channel, args);
}
throw new Error(`Invalid IPC channel: ${channel}`);
},
});
安全检查清单
始终使用以下设置配置 webPreferences:
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true, // REQUIRED
enableRemoteModule: false, // REQUIRED
sandbox: true, // REQUIRED
nodeIntegration: false, // REQUIRED
webSecurity: true,
}
IPC 通信
主进程处理程序
ipcMain.handle("db:insert", async (event, data: unknown) => {
if (!isValidInsertData(data)) {
throw new Error("Invalid data");
}
return db.insert(data);
});
安全规则
- 在预加载脚本中将所有 IPC 通道列入白名单
- 在主进程处理程序中验证所有参数
- 绝不信任来自渲染进程的用户输入
- 仅在主进程中保存机密信息
配置
electron-vite.config.ts
import { defineConfig } from "electron-vite";
export default defineConfig({
main: {
build: {
outDir: "dist/main",
rollupOptions: {
external: ["better-sqlite3", "native-module-name"],
},
},
},
preload: {
build: { outDir: "dist/preload" },
},
renderer: {
build: {
outDir: "dist/renderer",
rollupOptions: {
output: {
manualChunks: {
vendor: ["react", "react-dom"],
},
},
},
},
},
});
原生模块
对于 better-sqlite3 等原生模块:
- 在 electron-vite 配置中将其从 rollup 中排除
- 在 Electron Builder 配置的
extraResources中包含它 - 在主进程中使用动态导入
- 使用
@electron/rebuild为 Electron 重新构建
常见问题
绝不要这样做
// Exposing entire Node.js API
contextBridge.exposeInMainWorld("require", require);
// Not validating IPC messages
ipcMain.handle("dangerous", (event, data) => {
fs.writeFileSync(data.path, data.content);
});
// Using __dirname in renderer
const imagePath = `${__dirname}/images/logo.png`;
应该这样做
// Whitelist specific channels
contextBridge.exposeInMainWorld("electronAPI", {
invoke: (channel: string, args: unknown) => {
if (!["safe:channel"].includes(channel)) throw new Error("Invalid");
return ipcRenderer.invoke(channel, args);
},
});
// Validate all arguments
ipcMain.handle("file:write", async (event, { path, content }) => {
if (typeof path !== "string" || typeof content !== "string") {
throw new TypeError("Invalid arguments");
}
// Safe to use
});
验证检查清单
完成涉及 Electron 的任务前:
- 已启用安全设置(
contextIsolation、sandbox,且未启用nodeIntegration) - 已在预加载脚本中将 IPC 通道列入白名单
- 已在主进程中验证所有 IPC 参数
- 已将原生模块从打包器中排除,并包含在 extraResources 中
- 机密信息仅保存在主进程中(未暴露给渲染进程)
- 运行类型检查(
pnpm run typecheck)和测试(pnpm run test)
故障排除
| 问题 | 解决方案 |
|---|---|
| 生产环境中显示白屏 | 检查资源路径是否使用 base: './',并验证构建输出 |
| 原生模块失败 | 将其从 rollup 中排除,并包含在 extraResources 中 |
| IPC 无法工作 | 验证预加载脚本路径、是否启用了 contextIsolation,以及通道是否已列入白名单 |
| HMR 无法工作 | 使用 -w 标志运行,并检查 VITE_DEV_SERVER_URL |
有关详细配置示例和其他模式,请参阅 references/patterns.md。
评论
支持 Markdown