共计 2494 个字符,预计需要花费 7 分钟才能阅读完成。
技术选型分析
在构建跨平台桌面应用时,Electron、Tauri 和 Wails 是三个主要候选方案。经过对比,我们最终选择了 Electron,主要有以下考虑:

- 生态成熟度 :Electron 拥有最庞大的社区和插件生态,遇到问题更容易找到解决方案
- 开发体验 :Electron 支持热重载,配合 React 开发效率极高
- 跨平台一致性 :相比 Tauri 的 Rust 后端,Electron 能保证各平台更一致的表现
- 功能完整性 :Electron 提供完整的桌面 API,包括系统托盘、通知等
不过 Electron 也存在内存占用较高的问题,我们通过以下方式优化:
- 启用上下文隔离和沙箱模式
- 使用 V8 代码缓存
- 延迟加载非核心模块
核心实现
API 密钥安全存储
我们采用 OAuth2.0 流程获取 API 密钥,并使用 Node.js 的 crypto 模块进行加密:
import {encrypt, decrypt} from './crypto';
// 加密存储
const storeKey = (key: string) => {const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(process.env.ENCRYPTION_KEY), iv);
let encrypted = cipher.update(key);
encrypted = Buffer.concat([encrypted, cipher.final()]);
fs.writeFileSync('key.bin', iv.toString('hex') + ':' + encrypted.toString('hex'));
};
进程间通信
Electron 的主进程和渲染进程通过 IPC 通信,我们建立了类型安全的通信通道:
// preload.ts
exposeInMainWorld('electronAPI', {sendPrompt: (prompt: string) => ipcRenderer.invoke('prompt:send', prompt)
});
// main.ts
ipcMain.handle('prompt:send', async (_, prompt) => {return await chatGPT.send(prompt);
});
消息历史存储
使用 SQLite 存储聊天记录,表结构设计如下:
CREATE TABLE messages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
role TEXT CHECK(role IN ('user', 'assistant')),
content TEXT,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
);
性能优化
流式消息接收
通过 WebSocket 实现消息的实时流式传输:
const ws = new WebSocket('wss://api.openai.com/v1/chat');
ws.onmessage = (event) => {const data = JSON.parse(event.data);
if (data.choices[0].finish_reason === 'stop') {ws.close();
} else {updateMessage(data.choices[0].delta.content);
}
};
本地缓存策略
实现 LRU 缓存控制内存使用:
class LRUCache {private map = new Map<string, string>();
private maxSize: number;
constructor(maxSize: number) {this.maxSize = maxSize;}
get(key: string): string | undefined {const value = this.map.get(key);
if (value) {this.map.delete(key);
this.map.set(key, value);
}
return value;
}
}
生产环境注意事项
代码安全
- 使用 electron-builder 的 ASAR 打包
- 启用混淆:
"build": {"asar": true, "asarUnpack": "*.node"} - 设置 Content-Security-Policy
自动更新
基于 electron-updater 实现:
autoUpdater.checkForUpdatesAndNotify();
autoUpdater.on('update-downloaded', () => {autoUpdater.quitAndInstall();
});
CI/CD 配置
GitHub Actions 多平台构建配置示例:
jobs:
build:
strategy:
matrix:
os: [macos-latest, ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@v3
- run: npm ci
- run: npm run build:${{matrix.os}}
完整项目参考
GitHub 仓库包含完整实现:
项目地址 (包含 JSDoc 和单元测试)
扩展思考:插件系统设计
要实现支持 Midjourney 等第三方 AI 的插件系统,可以考虑:
-
设计统一的插件接口:
interface AIPlugin { name: string; execute: (input: string) => Promise<string>; render: (output: string) => JSX.Element; } -
使用动态导入加载插件:
const plugins = await Promise.all(pluginPaths.map(async (path) => {const module = await import(path); return module.default; }) ); -
为不同类型 AI 设计适配器模式,统一处理各种 API 响应格式
通过这种架构,可以轻松扩展支持 Stable Diffusion、Claude 等其他 AI 服务,同时保持核心代码的稳定性。
正文完
