# electron-template **Repository Path**: ErGeAnan/electron-template ## Basic Information - **Project Name**: electron-template - **Description**: 一个开箱即用的 Electron + Vue 3 + TypeScript 桌面应用模板。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-11-12 - **Last Updated**: 2026-11-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Electron 模板 一个开箱即用的 Electron + Vue 3 + TypeScript 桌面应用模板。 ## 技术栈 | 类别 | 技术 | 版本 | |------|------|------| | 桌面框架 | Electron | ^33 | | 打包工具 | Electron Forge | ^8 | | 前端框架 | Vue 3 | ^3.5 | | 前端路由 | Vue Router | ^5 | | 构建工具 | Vite | ^8 | | 类型系统 | TypeScript | ^5 | | 安装包 | NSIS + ZIP | - | ## 目录结构 ``` . ├── forge.config.ts # Electron Forge 打包配置 ├── vite.main.config.ts # 主进程 Vite 构建配置 ├── vite.preload.config.ts # 预加载脚本 Vite 构建配置 ├── vite.renderer.config.ts # 渲染进程 Vite 构建配置 ├── tsconfig.json # TS 根配置(引用 node + web) ├── tsconfig.node.json # 主进程 / 构建工具 TS 配置 ├── tsconfig.web.json # 渲染进程 TS 配置 ├── package.json ├── file.ico # 应用图标 ├── src/ │ ├── main/ # 主进程 │ │ ├── index.ts │ │ └── types.d.ts │ ├── preload/ # 预加载脚本(contextBridge 暴露 API) │ │ └── index.ts │ └── renderer/ # 渲染进程(Vue 3 SPA) │ ├── index.html │ └── src/ │ ├── main.ts │ ├── App.vue │ ├── env.d.ts │ ├── router/index.ts │ ├── types/electron.d.ts # window.electron 类型声明 │ └── views/ │ ├── A.vue │ └── B.vue └── .vite/ # 构建输出(自动生成) ``` ## 快速开始 ```bash # 安装依赖 npm install # 开发模式(热重载 + 自动打开 DevTools) npm run dev # 仅类型检查 npm run typecheck # 本地打包(不生成安装程序) npm run package # 完整打包(生成 NSIS 安装程序 + ZIP) npm run make ``` ## 三进程架构 ``` ┌─────────────────────────────────────────────────────┐ │ Electron 进程模型 │ ├──────────┬──────────────────┬────────────────────────┤ │ 主进程 │ 预加载进程 │ 渲染进程 │ │ Node.js │ 沙箱化 Node │ Chromium + Vue 3 │ │ src/main │ src/preload │ src/renderer │ │ │ │ │ │ 创建窗口 │ contextBridge │ 调用 window.electron │ │ 注册 IPC │ 暴露安全 API │ .ipcRenderer.invoke() │ │ 系统托盘 │ │ │ └──────────┴──────────────────┴────────────────────────┘ ▲ │ ▲ │ IPC 通信 │ │ └───────────────┴───────────────┘ ``` ### 主进程(Main) 应用的核心,负责创建窗口、注册 IPC handler、系统托盘等。入口 `src/main/index.ts`。 预加载脚本的路径配置: ```ts webPreferences: { preload: join(__dirname, '../preload/index.cjs'), contextIsolation: true, // 开启上下文隔离,renderer 无法直接访问 Node nodeIntegration: false, // 禁用 Node 集成 sandbox: false } ``` ### 预加载脚本(Preload) 通过 `contextBridge` 把有限的 IPC 能力安全地暴露到 renderer 的 `window` 对象上。入口 `src/preload/index.ts`: ```ts contextBridge.exposeInMainWorld('electron', { ipcRenderer: { invoke: (channel, ...args) => ipcRenderer.invoke(channel, ...args), send: (channel, ...args) => ipcRenderer.send(channel, ...args), on: (channel, listener) => ipcRenderer.on(channel, listener), once: (channel, listener) => ipcRenderer.once(channel, listener), } }) ``` ### 渲染进程(Renderer) Vue 3 SPA,开发时走 Vite dev server(由 Forge 的 Vite 插件自动启动),生产时加载打包好的静态文件。 ## IPC 通信 **主进程注册 handler:** ```ts // src/main/index.ts ipcMain.handle('cpu:info', () => os.cpus()[0].model) ``` **渲染进程调用:** ```ts const cpuInfo = await window.electron.ipcRenderer.invoke('cpu:info') ``` channel 名称采用 `模块:动作` 格式(如 `cpu:info`、`network:interfaces`)。 ## 类型声明 TypeScript 不知道 `window.electron` 的存在,需在 renderer 侧独立声明。文件:`src/renderer/src/types/electron.d.ts` ```ts type IpcRendererLike = { invoke: (channel: string, ...args: unknown[]) => Promise send: (channel: string, ...args: unknown[]) => void on: (channel: string, listener: (...args: unknown[]) => void) => void once: (channel: string, listener: (...args: unknown[]) => void) => void } declare global { interface Window { electron: { ipcRenderer: IpcRendererLike } } } export {} ``` **注意**:preload 源码里的 `declare global` 只对 preload 编译自身生效,renderer 不会读取 preload 的类型,所以 renderer 侧必须独立维护一份。新增 API 时,preload 的 `exposeInMainWorld` 和 renderer 的 `.d.ts` 要同步修改。 ## 开发调试 - **自动打开 DevTools**:开发模式启动时自动 detach 打开 - **F12 切换 DevTools**:开发模式下按 F12 开关 - **热重启**:`forge.config.ts` 中 `hotRestart: true`,主进程改动会自动重启 - **守卫条件**:DevTools 相关逻辑放在 `if (MAIN_WINDOW_VITE_DEV_SERVER_URL)` 内,该变量由 Forge Vite 插件注入——**开发时是 dev server URL,打包后是 `undefined`**,生产包不会执行 ## 构建产物 运行 `npm run make` 后,`out/` 目录下生成: | 产物 | 说明 | |------|------| | `electron-Setup-1.0.0.exe` | NSIS 安装程序(可选安装目录) | | `electron-win32-x64-1.0.0.zip` | 免安装绿色版压缩包 | `.vite/` 目录是中间构建产物(main/preload/renderer 各自的编译输出),由 Forge 在打包时自动读取。 ## ASAR 打包 `forge.config.ts` 中 `asar: true`,应用代码会被打包成单个 `app.asar` 文件,保护源码并减小体积。主进程中用 `join(__dirname, 'xxx')` 拼接路径时,Electron 会自动处理 asar 路径映射。 ## 扩展方向 - **新增 IPC**:主进程加 `ipcMain.handle/on` → preload 按需暴露 → renderer 加 `case` 调用 → `.d.ts` 里同步补类型 - **新增 BrowserWindow**:参考 `createWindow`,注意每个窗口都要独立配置 `webPreferences.preload` - **全局快捷键**:用 Electron 的 `globalShortcut` 模块在主进程注册 - **自动更新**:集成 `electron-updater`